home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Kernel / Em / mobility.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-17  |  93.7 KB  |  2,985 lines

  1. /*  C O P Y R I G H T   N O T I C E :                                     */
  2. /* Copyright 1986 Eric Jul and Norm Hutchinson.     May not be used for any  */
  3. /* purpose without written permission from the authors.              */
  4. /* Modifications copyright 1988, 1989 Clinton Jeffery, just for eric      */
  5.  
  6. #include "Kernel/h/system.h"
  7. #include "Kernel/h/assert.h"
  8. #include "Kernel/h/macros.h"
  9. #include "Kernel/h/errMsgs.h"
  10. #include "Kernel/h/mmCodes.h"
  11. #include "Kernel/h/emTypes.h"
  12. #include "Kernel/h/timerTypes.h"
  13. #include "Kernel/h/kmdTypes.h"
  14. #include "Kernel/h/kEvents.h"
  15. #include "Kernel/h/emCodes.h"
  16. #include "Kernel/h/mmMsgTypes.h"
  17. #include "Kernel/h/lmTypes.h"
  18. #include "Kernel/h/emkDefs.h"
  19. #include "Kernel/h/lmCodes.h"
  20. #include "Kernel/h/hotsTypes.h"
  21. #include "Kernel/h/map.h"
  22. #include "Kernel/h/set.h"
  23. #include "Kernel/h/consts.h"
  24. #include "Kernel/h/utils.h"
  25.  
  26. /*
  27.  * CHECKPOINT support is now integrated into this module-- 7/22/88 cjeffery
  28.  *
  29.  * Throughout the move _delivery_ subsystem, a null LMHandle
  30.  * signifies a Checkpoint operation instead of the usual move.
  31.  * The recovery subsystem typically uses LMHandles as replicantPtrs.
  32.  */
  33. #define ISCHECKPOINT (!fHandlePtr)
  34.  
  35. extern int ReturnOffStack;  /* Label in assembly code (!) */
  36. extern void StartProcessAtAddr();
  37. extern EmLocation           thisNodeLocation;
  38.  
  39. extern int                  cEmRunnable;
  40. extern SSPtr                removeQ(), preemptRunning(), stoppedQ, readyQ,
  41.                 NewStackSegment();
  42. extern void                 insertQ(), schedule(), FreeUpMovedStackSegment();
  43. extern ODTag                stdCodeODTag, stdGODTag, stdSSODTag;
  44. extern void                 fail(), unavail();
  45. extern void                 AddToTTable(), DigestTable(), MoveToTTable(),
  46.                 MoveARs(), AddCodeAddrToTTable(),
  47.                             MoveVarToTTable(), AddVarToTTable(),
  48.                             AddReqToTTable(), TranslateVar();
  49. extern char                *BrandNames[];
  50. extern Boolean              LoadRequest();
  51. extern void                 OTInsert(), EnsureRemovedFromInvokeQueue();
  52. extern ODP                  OTLookup(), getFreeOD();
  53. extern Boolean              MoveDownStack();
  54. extern void                 FindParamSizes();
  55. extern OID                  getNextOID();
  56. extern CodeAddr             TranslateCodeAddr();
  57. extern GenericReqPtr        TranslateReq();
  58. extern EmLocation           NewLocation();
  59. extern void                 UpdateLocation();
  60. extern TTMoveCondEntry      moveCondEntry;
  61. extern Map                  condMap;
  62. extern void                 ActivateCond(), DeActivateCond();
  63. extern void                 UnblockInitially();
  64.  
  65. /* Counters from measure.c */
  66. extern int            cMV_MovesDone, cMV_MovesBytesSent;
  67. extern int            cMV_MovesPacketsSent;
  68.  
  69. /*Forward */
  70. void           FixInvokeQueue();
  71. void           MoveMonitorToTTable();
  72. void           MoveSSODToTTable();
  73. HResult        RecoverCallBack();
  74. void _realMoveCallBack();
  75.  
  76. /************************************************************************/
  77. /*  Fixing and unfixing global objects                                  */
  78. /************************************************************************/
  79.  
  80. void Fix(fODP, fNewLocation)
  81. register ODP                 fODP;
  82. register ODP                 fNewLocation;
  83. /*  fix the object pointed to */
  84. {
  85.     KMDTrace("FixMe", 3, "(Fix me: Fix is not fully implemented) %x %x\n",
  86.     fODP, fNewLocation);
  87.     
  88.     /* if integer or immutable then fail */
  89.     /* if local then fail */
  90.     /* if new location is here then */
  91.     /* if global and resident, set fixed bit */
  92.     /* if global and non-resident, do remote fix */
  93.     /* if new location is NOT here, and object is, then */
  94.     /* call upon move protocol */
  95.     /* if neither location nor object is here then forward req to new
  96.     location */
  97. }
  98.  
  99.  
  100. void UnFix(fODP, fNewLocation)
  101. register ODP                 fODP;
  102. register ODP                 fNewLocation;
  103. /*  unfix the object pointed to */
  104. {
  105.     KMDTrace("FixMe", 3, "(Fix me: UnFix is not fully implemented) %x %x\n",
  106.     fODP, fNewLocation);
  107.     
  108.     /* if integer or immutable then fail */
  109.     /* if local then fail */
  110.     /* if global and resident, set fixed bit */
  111.     /* if global and non-resident, do remote fix */
  112. }
  113.  
  114. void IsFixed(fODP)
  115. register ODP                 fODP;
  116. /* return true iff the object is fixed somewhere */
  117. {
  118.     KMDTrace("FixMe", 3, "(Fix me: IsFixed is not fully implemented) %x %x\n",
  119.     fODP);
  120.     /* If integer then ??? */
  121.     /* If local then ??? */
  122.     /* If global & resident then check for isFixed */
  123.     /* else forward request */
  124.     currentSSP->resultBrand = DataBrand;
  125.     currentSSP->regs.arg1 = FALSE;
  126. }
  127. /**********************************************************************/
  128. /**********************************************************************/
  129.  
  130. /**********************************************************************/
  131. /*      TraverseAndMoveARList                                         */
  132. /**********************************************************************/
  133.  
  134. void TraverseAndMoveARList(fGODP, fARSet)
  135. GODP                        fGODP;
  136. Set                         fARSet;
  137. {
  138.     register InvokeQueuePtr q, head;
  139.     register SSAddr         l;
  140.     
  141.     KMDTrace("Move", 4, "Traversing AR list for GODP 0x%06x, %s\n", fGODP,
  142.     PPGOID(fGODP->ownOID));
  143.     head            = &fGODP->ARListHead;
  144.     for (q = head->next; q != head; q = q->next) {
  145.     l = mLFromInvokeQueuePtr(q);
  146.     KMDTrace("Move", 5, "Adding l = 0x%06x to ARSet\n", l);
  147.     Set_Insert(fARSet, (int) l);
  148.     }
  149. }
  150.  
  151.  
  152.  
  153. /*
  154.  * TraverseAndTranslateDataArea
  155.  *
  156.  * Traverse the data area of the given object and translate it according
  157.  * to the given map.
  158.  */
  159. void TraverseAndTranslateDataArea(fODP, fMap, isRecovery)
  160. ODP fODP;
  161. Map fMap;
  162. {
  163.   register TemplateEntryPtr t;
  164.   register int              i;
  165.   register Bytes           *dataAddr;
  166.   CodePtr                   cPtr;
  167.   TemplatePtr               theTemplate;
  168.   char kmdDest[12];
  169.  
  170.   assert(fODP->G.tag.tag == GODataTag || fODP->G.tag.tag == LOTag);
  171.   strcpy(kmdDest,(isRecovery ? "Recover" : "Move"));
  172.  
  173.   /* Translate CodePtr */
  174.   cPtr = (CodePtr) Map_Lookup(fMap, (int) fODP->L.myCodePtr);
  175.  
  176.   KMDTrace(kmdDest, 4, "Translating 0x%04x using code %s\n",
  177.        fODP, PPCodePtr(cPtr));
  178.   KMDTrace(kmdDest, 5, "CodePtr: (0x%05x -> 0x%05x) one of %s\n",
  179.        fODP->L.myCodePtr, cPtr, PPCodePtr(cPtr));
  180.  
  181.   assert(NonNIL(cPtr));
  182.  
  183.   fODP->L.myCodePtr = cPtr;
  184.     
  185.   KMDTrace(kmdDest, 5, "Instance size (from code): %d\n", cPtr->instanceSize);
  186.  
  187.   assert(cPtr->ODATemplateOffset);
  188.     
  189.   theTemplate = (TemplatePtr) addOffset(cPtr, cPtr->ODATemplateOffset);
  190.   KMDTrace(kmdDest, 5, "Number of template entries %d\n",
  191.        theTemplate->B.numEntries);
  192.  
  193.   t = &theTemplate->entry[0];
  194.  
  195.   if (fODP->L.tag.replicated) {
  196.     dataAddr = (Bytes *) &fODP->R.inlineData[0];
  197.   } else dataAddr = (Bytes *) &fODP->L.inlineData[0];
  198.  
  199.   KMDTrace(kmdDest, 5, "Data starts at 0x%05x\n", dataAddr);
  200.   for (i = 0; i < theTemplate->B.numEntries; i++) {
  201.  
  202.     switch (t->TE.SS.Format) {
  203.  
  204.     case ShortStaticF: {
  205.       KMDTrace(kmdDest, 5, "\tShortStaticF\t(%s) %s\tcount =%4d\n", 
  206.            BrandNames[(int)t->TE.SS.theBrand],
  207.            t->TE.SS.paramInfo != 0 ? "isParam" : " ",
  208.            t->TE.SS.count);
  209.  
  210.       switch (t->TE.SS.theBrand) {
  211.  
  212.       case DataBrand: {
  213.     register int j;
  214.     for (j = 0; j < t->TE.SS.count; j+=sizeof(int))
  215.       KMDTrace(kmdDest, 5, "%6d: Data:  %08x\n",
  216.            (dataAddr + j) - (Bytes *) fODP, * ((int *)(dataAddr + j)));
  217.     dataAddr += (t->TE.SS.count == 1 ? 4: t->TE.SS.count);
  218.     break;
  219.       }
  220.         
  221.       case ODPBrand: {
  222.     register int  j;
  223.     register ODP *ODPAddr;
  224.     int oldValue;
  225.         
  226.     for (j = 1; j <= t->TE.SS.count; j++) {
  227.       oldValue =  * (int *) dataAddr;
  228.       ODPAddr = (ODP *) dataAddr;
  229.       *ODPAddr = (ODP) Map_Lookup(fMap, (int) oldValue);
  230.       KMDTrace(kmdDest, 5, "%6d: ODP (0x%05x->0x%05x)\n", 
  231.            dataAddr - (Bytes *) fODP, oldValue, *ODPAddr);
  232.       dataAddr += sizeof(ODP);
  233.     }
  234.     break;
  235.       }
  236.  
  237.       case AddrBrand:{
  238.     assert(t->TE.SS.theBrand != AddrBrand);
  239.     dataAddr += t->TE.SS.count * sizeof(dataAddr);
  240.     break;
  241.       }
  242.  
  243.       case VectorBrand: {
  244.     register VectorAreaPtr  v;
  245.     register int            count;
  246.  
  247.     v         = (VectorAreaPtr) dataAddr;
  248.     dataAddr     = (Bytes *) &v->data[0];
  249.     count        = v->count;
  250.  
  251.     KMDTrace(kmdDest, 5, "\t\tElementBrand = %s, count %d\n",
  252.          BrandNames[(int)t->TE.SS.elementBrand], count);
  253.     KMDTrace(kmdDest, 5, "\t\tVector type %s\n",
  254.          PPCOID(fODP->L.myCodePtr->ownOID));
  255.  
  256.     switch (t->TE.SS.elementBrand) {
  257.  
  258.     case DataBrand: {
  259.       /* Do nothing */
  260.       if (fODP->L.myCodePtr->ownOID == (unsigned int) 0xff00008b) {
  261.         /* A real hack but for tracing only ... it is a string */
  262.         KMDTrace(kmdDest, 5, "\t\tString: %.*s\n", count, &v->data[0]);
  263.       }
  264.       dataAddr    += count;
  265.       break;
  266.     }
  267.  
  268.     case ODPBrand: {
  269.       register ODP *ODPAddr;
  270.       register int  j;
  271.       register ODP  oldODP; 
  272.       for (j = 0; j < count / sizeof(ODP); j++) {
  273.         ODPAddr     = (ODP *) dataAddr;
  274.         oldODP     =     *ODPAddr;
  275.         *ODPAddr     = (ODP)  Map_Lookup(fMap, (int) oldODP);
  276.         KMDTrace(kmdDest, 5,  "\t\t%6d: ODP (0x%05x) -> (0x%05x) %s\n", j,
  277.              oldODP, *ODPAddr, t->TE.SS.attachedFlag ? " Attached":"");
  278.         dataAddr += sizeof(ODP);
  279.       }
  280.       break;
  281.     }
  282.  
  283.     case VariableBrand:{
  284.       register int            j;
  285.       register AVariablePtr   varPtr;
  286.       int                     oldAbCon, oldODP;
  287.  
  288.       for (j = 0; j < count / sizeof(AVariable); j++){
  289.         varPtr = (AVariablePtr) dataAddr;
  290.         oldAbCon = (int) varPtr->myAbConPtr;
  291.         oldODP   = (int) varPtr->myAddr;
  292.         TranslateVar(varPtr, fMap);
  293.         KMDTrace(kmdDest, 5,
  294.              "\t\t%6d: Var (0x%01x, 0x%01x) -> (0x%01x, 0x%01x), %s\n",
  295.              j, oldAbCon, oldODP, varPtr->myAddr,
  296.              varPtr->myAbConPtr, PPVar(varPtr));
  297.         dataAddr += sizeof(AVariable);
  298.       }
  299.       break;
  300.     }
  301.  
  302.     default:
  303.       ErrMsg("Bad element brand, %s, in vector - compiler error\n",
  304.          PPBrand(t->TE.SS.elementBrand));
  305.     } /* switch on Vector element brand*/
  306.     break;
  307.       }
  308.  
  309.       case VariableBrand: {
  310.     register int            j;
  311.     register AVariablePtr   varPtr;
  312.     int                     oldAbCon, oldODP;
  313.  
  314.     for (j = 1; j <= t->TE.SS.count; j++) {
  315.       varPtr = (AVariablePtr) dataAddr;
  316.       oldAbCon = (int) varPtr->myAbConPtr;
  317.       oldODP   = (int) varPtr->myAddr;
  318.       TranslateVar(varPtr, fMap);
  319.       KMDTrace(kmdDest, 5,
  320.            "%6d: Var (0x%01x, 0x%01x) -> (0x%01x, 0x%01x), %s\n",
  321.            dataAddr - (Bytes *)fODP, oldAbCon, oldODP,
  322.            varPtr->myAddr, varPtr->myAbConPtr,
  323.            PPVar(varPtr));
  324.       dataAddr += sizeof(AVariable);
  325.     }
  326.     break;
  327.       }
  328.  
  329.       case MonitorBrand: {
  330.     register MonitorLockPtr     mPtr;
  331.     Offset                      monLockOffset;
  332.     MonitorLockPtr              oldmPtr;
  333.     ODP                         oldODP;
  334.  
  335.     mPtr = (MonitorLockPtr) dataAddr;
  336.     monLockOffset = byteOffset(fODP, dataAddr);
  337.  
  338.     if(isRecovery){ /* was ifndef IGNORENORM */
  339.       mPtr->isLocked = FALSE;
  340.       mPtr->waiting  = NULL;
  341.     }
  342.  
  343.     KMDTrace(kmdDest, 5, "%6d: Monitor %s\n", monLockOffset,
  344.          mPtr->isLocked ? "Locked" : "Open");
  345.     /*
  346.      * Enter the address of the monitor lock into the translation
  347.      * table so that Conditions can be translated correctly.
  348.      * Unfortunately, this is not easy since we do not have the
  349.      * original address of the monitorlock.  Instead, we have to
  350.      * reconstruct it.
  351.      */
  352.     oldODP = (ODP) Map_InverseLookup(fMap, (int) fODP);
  353.     KMDTrace(kmdDest, 5, "\tOld ODP of 0x%06x is 0x%06x\n", oldODP, fODP);
  354.     assert(NonNIL(oldODP));
  355.     oldmPtr = (MonitorLockPtr) addOffset(oldODP, monLockOffset);
  356.     KMDTrace(kmdDest, 5, "\tmonLock (0x%06x -> 0x%06x) insert\n",
  357.          oldmPtr, mPtr);
  358.     Map_Insert(fMap, (int) oldmPtr, (int) mPtr);
  359.  
  360.     KMDTrace(kmdDest, 5, "Old waiting 0x%06x\n", mPtr->waiting);
  361.     if (NonNULL(mPtr->waiting)) {
  362.       mPtr->waiting = (SSPtr) Map_Lookup(fMap, (int) mPtr->waiting);
  363.       KMDTrace(kmdDest, 5, "  --> new waiting 0x%06x\n",mPtr->waiting);
  364.       assert(NonNIL(mPtr->waiting));
  365.     }
  366.     dataAddr += sizeof(MonitorLock);
  367.     break;
  368.       }
  369.  
  370.       default:
  371.     ErrMsg("Bad brand: %s\n", PPBrand(t->TE.SS.theBrand));
  372.     (void) abort();
  373.       } /* switch */
  374.  
  375.       t = (TemplateEntryPtr) addOffset(t, sizeof(ShortStatic));
  376.       break;
  377.     }
  378.  
  379.     case RegisterF:
  380.       KMDTrace(kmdDest, 5, "\tRegisterF\t(%s),\t%s, r%d, count %d\n",
  381.            BrandNames[(int)t->TE.R.theBrand], 
  382.            t->TE.R.storedWhere == InRegister ? "InRegister" : "InSaveArea",
  383.            t->TE.R.reg, t->TE.R.count);
  384.       ErrMsg("Registers in data area -- compiler error\n");
  385.       assert(FALSE);
  386.       (void) abort();
  387.       break;
  388.  
  389.     default:
  390.       ErrMsg("Bad template format %d\n", t->TE.SS.Format);
  391.       assert(FALSE);
  392.       (void) abort();
  393.       break;
  394.     } /* switch (t->TE.SS.Format) */
  395.   }
  396. }
  397.  
  398. /*
  399.  * TraverseAndMove
  400.  *
  401.  * Traverse the data area of the given object and move any component objects
  402.  * that must follow it (i.e., attached, replicated, or local objects).
  403.  * fODP must point to a data area.
  404.  * fSentMap contains the ODPs already sent -- add the ODP sent to it.
  405.  * fARSet contains the ARs to be sent -- add any new ARs to it.
  406.  */
  407. void TraverseAndMove(fHandlePtr, fODP, fSentMap, fARSet)
  408. LMHandle *fHandlePtr;
  409. ODP       fODP;
  410. Map       fSentMap;
  411. Set       fARSet;
  412. {
  413.   register TemplateEntryPtr t;
  414.   register int              i;
  415.   register Bytes           *dataAddr;
  416.   register LODataPtr        dataPtr;
  417.   CodePtr                   cPtr;
  418.   TemplatePtr               theTemplate;
  419.   char kmddest[12];
  420.  
  421.   strcpy(kmddest,(ISCHECKPOINT?"Checkpoint":"Move"));
  422.  
  423.   dataPtr                   = (LODataPtr) fODP;
  424.  
  425.   assert(dataPtr->tag.tag == GODataTag || dataPtr->tag.tag == LOTag);
  426.  
  427.   cPtr = fODP->L.myCodePtr;
  428.   assert(NonNIL(cPtr));
  429.   KMDTrace(kmddest, 4, "Sending subcomponents of 0x%04x using code %s\n",
  430.        fODP, PPCodePtr(cPtr));
  431.  
  432.   KMDTrace(kmddest, 5, "Instance size (from code): %d\n", cPtr->instanceSize);
  433.  
  434.   assert(NonNULL(cPtr->ODATemplateOffset));
  435.   theTemplate = (TemplatePtr) addOffset(cPtr, cPtr->ODATemplateOffset);
  436.   KMDTrace(kmddest, 5, "Number of template entries %d\n",
  437.        theTemplate->B.numEntries);
  438.  
  439.   t = &theTemplate->entry[0];
  440.  
  441.   dataAddr =
  442.     (Bytes *)(fODP->L.tag.replicated? fODP->R.inlineData : fODP->L.inlineData);
  443.  
  444.   KMDTrace(kmddest, 5, "Data starts at 0x%05x\n", dataAddr);
  445.   for (i = 0; i < theTemplate->B.numEntries; i++) {
  446.  
  447.     switch (t->TE.SS.Format) {
  448.  
  449.     case ShortStaticF: {
  450.       KMDTrace(kmddest, 5, "\tShortStaticF\t(%s) %s\tcount =%4d\n", 
  451.            BrandNames[(int)t->TE.SS.theBrand],
  452.            t->TE.SS.paramInfo != 0 ? "isParam" : " ",
  453.            t->TE.SS.count);
  454.  
  455.       switch (t->TE.SS.theBrand) {
  456.  
  457.       case DataBrand: {
  458.     register int j;
  459.     for (j = 0; j < t->TE.SS.count; j+=sizeof(int))
  460.       KMDTrace(kmddest, 5, "%6d: Data:  %08x\n",
  461.            (dataAddr + j) - (Bytes *) fODP, * ((int *)(dataAddr + j)));
  462.     dataAddr += (t->TE.SS.count == 1 ? 4 : t->TE.SS.count);
  463.     break;
  464.       }
  465.  
  466.       case ODPBrand: {
  467.     register int  j;
  468.     register ODP *ODPAddr;
  469.  
  470.     for (j = 1; j <= t->TE.SS.count; j++) {
  471.       ODPAddr = (ODP *) dataAddr;
  472.       KMDTrace(kmddest, 5, "%6d: ODP (0x%05x)%s\n", 
  473.            dataAddr - (Bytes *) fODP, *ODPAddr,
  474.            t->TE.SS.attachedFlag ? " Attached" : "");
  475.       if (t->TE.SS.attachedFlag) {
  476.         MoveToTTable(fHandlePtr, *ODPAddr, fSentMap, fARSet);
  477.       } else {
  478.         AddToTTable(fHandlePtr, *ODPAddr, fSentMap, fARSet);
  479.       }
  480.       dataAddr += sizeof(ODP);
  481.     }
  482.     break;
  483.       }
  484.  
  485.       case AddrBrand: {
  486.     assert(t->TE.SS.theBrand != AddrBrand);
  487.     dataAddr += t->TE.SS.count * sizeof(dataAddr);
  488.     break;
  489.       }
  490.  
  491.       case VectorBrand: {
  492.     register VectorAreaPtr  v;
  493.     register int            count;
  494.  
  495.     v     = (VectorAreaPtr) dataAddr;
  496.     dataAddr= (Bytes *) v->data;
  497.     count    = v->count;
  498.  
  499.     KMDTrace(kmddest, 5, "\t\tElementBrand = %s, count %d\n",
  500.          BrandNames[(int)t->TE.SS.elementBrand], count);
  501.     KMDTrace(kmddest, 5, "\t\tVector type %s\n",
  502.          PPCOID(fODP->L.myCodePtr->ownOID));
  503.  
  504.     switch (t->TE.SS.elementBrand) {
  505.  
  506.     case DataBrand: {
  507.       /* Do nothing */
  508.       if (fODP->L.myCodePtr->ownOID == (unsigned int) 0xff00008b) {
  509.         KMDTrace(kmddest, 5, "\t\tString count %d\n", count);
  510.         KMDTrace(kmddest, 5, "\t\tString: %.*s\n", count, v->data);
  511.       }
  512.       dataAddr += (count == 1 ? 4 : count);
  513.       break;
  514.     }
  515.  
  516.     case ODPBrand: {
  517.       register ODP *ODPAddr;
  518.       register int  j;
  519.  
  520.       for (j = 0; j < count / sizeof(ODP); j++) {
  521.         ODPAddr = (ODP *) dataAddr;
  522.         KMDTrace(kmddest, 5, "\t\t%6d: ODP (0x%05x)%s\n", 
  523.              j, *ODPAddr, t->TE.SS.attachedFlag ? " Attached" : "");
  524.         if (t->TE.SS.attachedFlag) {
  525.           MoveToTTable(fHandlePtr, *ODPAddr, fSentMap, fARSet);
  526.         } else {
  527.           AddToTTable(fHandlePtr, *ODPAddr, fSentMap, fARSet);
  528.         }
  529.         dataAddr += sizeof(ODP);
  530.       }
  531.       break;
  532.     }
  533.  
  534.     case VariableBrand: {
  535.       register AVariablePtr varPtr;
  536.       register int          j;
  537.  
  538.       for (j = 0; j < count / sizeof(AVariable); j++) {
  539.         varPtr = (AVariablePtr) dataAddr;
  540.         KMDTrace(kmddest, 5, "\t\t%6d: Var (0x%01x, 0x%01x), %s%s\n",
  541.              j, varPtr->myAddr, varPtr->myAbConPtr,
  542.              t->TE.SS.attachedFlag ? "Attached " : "", PPVar(varPtr));
  543.         if (t->TE.SS.attachedFlag) {
  544.           MoveVarToTTable(fHandlePtr, varPtr, fSentMap, fARSet);
  545.         } else {
  546.           AddVarToTTable(fHandlePtr, varPtr, fSentMap, fARSet);
  547.         }
  548.         dataAddr += sizeof(AVariable);
  549.       }
  550.       break;
  551.     }
  552.  
  553.     default: {
  554.       ErrMsg("Bad element brand, %s, in vector - compiler error\n",
  555.          PPBrand(t->TE.SS.elementBrand));
  556.       (void) abort();
  557.     }
  558.     } /* switch (t->TE.SS.elementBrand) */
  559.     break;
  560.       }
  561.  
  562.       case VariableBrand: {
  563.     register int          j;
  564.     register AVariablePtr varPtr;
  565.  
  566.     for (j = 1; j <= t->TE.SS.count; j++){
  567.       varPtr = (AVariablePtr) dataAddr;
  568.       KMDTrace(kmddest, 5, "%6d: Var (0x%01x, 0x%01x), %s%s\n",
  569.            dataAddr-(Bytes *)fODP, varPtr->myAddr, varPtr->myAbConPtr,
  570.            t->TE.SS.attachedFlag ? "Attached " : "", PPVar(varPtr));
  571.       if (t->TE.SS.attachedFlag) {
  572.         MoveVarToTTable(fHandlePtr, varPtr, fSentMap, fARSet);
  573.       } else {
  574.         AddVarToTTable(fHandlePtr, varPtr, fSentMap, fARSet);
  575.       }
  576.       dataAddr += sizeof(AVariable);
  577.     }
  578.     break;
  579.       }
  580.  
  581.       case MonitorBrand: {
  582.     register MonitorLockPtr mPtr;
  583.     register SSPtr          p;
  584.  
  585.     mPtr = (MonitorLockPtr) dataAddr;
  586.     KMDTrace(kmddest, 5, "%6d: Monitor %s\n", 
  587.          dataAddr - (Bytes *) fODP,mPtr->isLocked ? "Locked" : "Open");
  588.     if (NonNULL(mPtr->waiting)) {
  589.       KMDTrace(kmddest, 4, "Processes awaiting entry:\n");
  590.       p = mPtr->waiting;
  591.       do {
  592.         p = getRQLink(p);
  593.         KMDTrace(kmddest, 5, "\t%s in %s\n",
  594.              PPPOID(p->processOID), PPSSPlace(p));
  595.       } while (p != mPtr->waiting);
  596.     }
  597.     if(!ISCHECKPOINT)
  598.       MoveMonitorToTTable(fHandlePtr, mPtr, fSentMap, fARSet);
  599.     dataAddr += sizeof(MonitorLock);
  600.     break;
  601.       }
  602.  
  603.       default:
  604.     KMDTrace(kmddest, 5, "Bad brand, %s, in TraverseAndMove\n",
  605.          PPBrand(t->TE.SS.theBrand));
  606.     (void) abort();
  607.  
  608.  
  609.       } /* end switch (t->TE.SS.theBrand) */
  610.  
  611.       t = (TemplateEntryPtr) addOffset(t, sizeof(ShortStatic));
  612.       break;
  613.     }
  614.  
  615.     case RegisterF: {
  616.       KMDTrace(kmddest, 5, "\tRegisterF\t(%s), %s, reg = %4d, count %d\n",
  617.            PPBrand(t->TE.R.theBrand),
  618.            t->TE.R.storedWhere == InRegister ? "InRegister" : "InSaveArea",
  619.            t->TE.R.reg, t->TE.R.count);
  620.       ErrMsg("Fix me: registers in data area ???\n");
  621.       assert(FALSE);
  622.       (void) abort();
  623.       break;
  624.     }
  625.  
  626.     default:
  627.       KMDTrace(kmddest, 5, "Bad format %d\n", t->TE.SS.Format);
  628.       (void) abort();
  629.       break;
  630.  
  631.     } /* switch (t->TE.SS.Format) */
  632.   } /* for ( ... ) */
  633. }
  634.  
  635.  
  636. /*
  637.  * TraverseAndTranslate
  638.  *
  639.  * Traverse the data area of the given object and translate it according
  640.  * to the map given.
  641.  */
  642. void TraverseAndTranslate(fODP, fMap, isRecovery)
  643. ODP fODP;
  644. Map fMap;
  645. int isRecovery;
  646. {
  647.   char kmdDest[8];
  648.  
  649.   strcpy(kmdDest,(isRecovery ? "Recover" : "Move"));
  650.   KMDTrace("TT", 5, "TraverseAndTranslate(0x%01x) one of %s\n",
  651.        fODP, PPODTag(fODP->G.tag));
  652.  
  653.   switch (fODP->G.tag.tag) {
  654.  
  655.   case GODTag:
  656.     KMDTrace(kmdDest, 5, "Translate GOD @ %s dataPtr 0x%04x, one of %s\n",
  657.          PPLoc(fODP->G.ownLoc),fODP->G.dataPtr, PPCOID(fODP->G.myCodeOID));
  658.  
  659.     /* Ought to have ARListHead here */
  660.     TraverseAndTranslateDataArea((ODP) fODP->G.dataPtr, fMap, isRecovery);
  661.     if(!isRecovery){
  662.       fODP->G.tag.setUpDone   = TRUE;
  663.       fODP->G.tag.frozen      = FALSE;
  664.       UnblockInitially((GODP) fODP);
  665.     }
  666.     break;
  667.  
  668.     
  669.   case GODataTag:
  670.   case LOTag: {
  671.     TraverseAndTranslateDataArea(fODP, fMap, isRecovery);
  672.     break;
  673.   }
  674.  
  675.   case CondTag:{
  676.     MonitorLockPtr theNewLock;    
  677.     KMDTrace(kmdDest, 5, "Translate Cond %s\n", PPODP(fODP));
  678.     theNewLock = (MonitorLockPtr) Map_Lookup(fMap, (int) fODP->CD.theLock);
  679.  
  680.     KMDTrace(kmdDest, 5, "Lock (0x%06x -> 0x%06x)\n",
  681.          fODP->CD.theLock, theNewLock);
  682.     fODP->CD.theLock = theNewLock;
  683.         
  684.     KMDTrace(kmdDest, 5, "Old waiting: 0x%06x\n", fODP->CD.waiting);
  685.     if (IsNULL(fODP->CD.waiting)) {
  686.       KMDTrace(kmdDest, 5, "No Waiting processes\n");
  687.     } else {
  688.       fODP->CD.waiting = (isRecovery ? 0 :
  689.               (SSPtr) Map_Lookup(fMap, (int) fODP->CD.waiting));
  690.       KMDTrace(kmdDest, 5, "New waiting: 0x%06x\n", fODP->CD.waiting);
  691.     }
  692.     fODP->CD.tag.setUpDone  = TRUE;
  693.     ActivateCond(theNewLock, (CondODP) fODP);
  694.     break;
  695.   }
  696.  
  697.   case SSTag: {
  698.     register SSODP          myODP;
  699.     register AVariablePtr   aVar;
  700.     register SSAddr         sAddr;
  701.     SSAddr                  l;
  702.     SSPtr                   p;
  703.     int                     oldAbCon;
  704.     int                     oldODP, delta;
  705.     CodePtr                 cPtr;
  706.     CodeAddr               *returnAddrAddr;
  707.     CodeAddr                ip = 0;
  708.     GODP                    b;
  709.     GODataPtr               g;
  710.     SSAddr                  sp;
  711.     RegisterSave            regs, nextRegs;
  712.     SSAddr                  *regStoredAt[16];
  713.     TemplatePtr             tPtr;
  714.     TemplateEntryPtr        entry;
  715.     DynamicLinkPtr          theLink;
  716.     int                     i, tOffset, it, k, argumentCount, resultCount;
  717.     IPMapPtr                templateMap;
  718.  
  719.     if(isRecovery) goto BADTAG;
  720.  
  721.     p     = (SSPtr) fODP;
  722.     myODP = p->ownSSODP;
  723.  
  724.     KMDTrace(kmdDest, 4, "Translating SSOD @ %s  OID: 0x%08x process %s\n",
  725.          PPLoc(myODP->ownLoc), myODP->ownOID, PPPOID(myODP->processOID));
  726.     KMDTrace(kmdDest, 5, "  SSPtr 0x%05x\n", p);
  727.     {
  728.       register SSAddr   **rs;
  729.       /*
  730.        * regStoredAt indicates the address of where a preempted
  731.        * register has been stored.  Further down in the stack
  732.        * we find the usage of the register and only then can
  733.        * we translate the stored value.
  734.        * The nextRegs is used for restoring register values
  735.        * while still using the current values.
  736.        */
  737.       KMDTrace("FixMe", 5, "Assume for RegisterF, regs before saved\n");
  738.  
  739.       for (rs = ®StoredAt[0]; rs != ®StoredAt[16]; rs++) {
  740.     *rs = (SSAddr *) NULL;
  741.       }
  742.  
  743.       /*
  744.        * The following ensure that the preempted registers will be
  745.        * translated.
  746.        */
  747.  
  748.       KMDTrace("Portability", 1, "Using absolute reg numbers!\n");
  749.       regStoredAt[4]  = (SSAddr *) &p->regs.r4;
  750.       regStoredAt[5]  = (SSAddr *) &p->regs.r5;
  751.       regStoredAt[6]  = (SSAddr *) &p->regs.r6;
  752.       regStoredAt[7]  = (SSAddr *) &p->regs.r7;
  753.       regStoredAt[8]  = (SSAddr *) &p->regs.r8;
  754.       regStoredAt[9]  = (SSAddr *) &p->regs.r9;
  755.     }
  756.  
  757.     /*
  758.      * Translate status information related to the SS -- primarily
  759.      * the Requests.
  760.      */
  761.  
  762.     if (IsNULL(p)) {
  763.       ErrMsg("** No actual stack segment ???? **\n");
  764.       (void) abort();
  765.     }
  766.  
  767.     if (NonNULL(p->invokePtr)) {
  768.       p->invokePtr = (GenericPtr) TranslateReq((GenericReqPtr) (p->invokePtr), fMap, p);
  769.     }
  770.  
  771.     if (NonNULL(p->rPtr)) {
  772.       p->rPtr = (GenericPtr) TranslateReq((GenericReqPtr) (p->rPtr), fMap, p);
  773.     }
  774.  
  775.     /*
  776.      * First go through the SS state information and translate it.
  777.      * Then translate requests (done above).
  778.      * Traverse and translate the stack area itself.
  779.      * 
  780.      * When Digesting the SS, the new address of the stack
  781.      * pointer was put into the translation map (cf. DigestTable).
  782.      * It may then be used for fixing all other addresses internal to
  783.      * the stack segment.
  784.      */
  785.  
  786.     /*
  787.      * Translate the ready queue link.
  788.      * Note, this is only meaningfull for processes that are moved
  789.      * while in queues -- for the time being only conditions and
  790.      * monitor entry.  These queues are transferred with their
  791.      * links as hard addresses and are reestablished merely by
  792.      * translating the hard addresses.   Thus the entire queue must
  793.      * be sent.  This method is not used for processes waiting in
  794.      * the ready queue since usually not all ready processes move at the
  795.      * same time.
  796.      */
  797.     if (NonNULL(p->readyQLink)) {
  798.       p->readyQLink   = (SSPtr) Map_Lookup(fMap, (int) p->readyQLink);
  799.       if (IsNIL(p->readyQLink)) p->readyQLink = NULL;
  800.     }
  801.     KMDTrace(kmdDest, 5, "ReadyQLink\t0x%06x\n", p->readyQLink);
  802.  
  803.     /* Translate registers */    
  804.     sp              = p->regs.sp;
  805.     p->regs.sp      = (SSAddr) Map_Lookup(fMap, (int) sp);
  806.     delta           = (Offset) byteOffset(sp, p->regs.sp);
  807.     KMDTrace(kmdDest, 5, "sp 0x%06x - > 0x%06x delta %d\n", sp, p->regs.sp, delta);
  808.     sAddr   = sp    = p->regs.sp;
  809.     regs            = p->regs;
  810.  
  811.     /* Translate return ip on top of stack */
  812.     ip              = (CodeAddr)   TranslateCodeAddr(fMap, * (CodeAddr *) sp);
  813.     returnAddrAddr  = (CodeAddr *) sp;
  814.     *returnAddrAddr = ip;
  815.  
  816.     p->regs.l       = (SSAddr) addOffset(p->regs.l, delta);
  817.     p->regs.b       = (GODP) Map_Lookup(fMap, (int) p->regs.b);
  818.     p->regs.g       = (GODataPtr) Map_Lookup(fMap, (int) p->regs.g);
  819.  
  820.     /*
  821.      * Translate the result registers (if necessary)
  822.      */
  823.     switch (p->resultBrand){
  824.     case DataBrand:
  825.       KMDTrace(kmdDest, 4, "Result regs data: (0x%04x,0x%04x)\n",
  826.            p->regs.arg1, p->regs.arg2);
  827.       break;
  828.  
  829.     case ODPBrand: {
  830.       ODP             theOldODP, newODP;
  831.  
  832.       theOldODP    = (ODP) p->regs.arg1;
  833.       newODP       = (ODP) Map_Lookup(fMap, (int) theOldODP);
  834.       p->regs.arg1 = (int) newODP; 
  835.       KMDTrace(kmdDest, 4, "Result reg ODP: (0x%06x -> 0x%06x) is %s\n",
  836.            theOldODP, newODP, PPODP((ODP) p->regs.arg1));
  837.       break;
  838.     }
  839.  
  840.     case VariableBrand: {
  841.       AVariablePtr        varPtr;
  842.       DataAddr            oldAddr;
  843.       AbConPtr            oldAbConPtr;
  844.       varPtr              = (AVariablePtr) &p->regs.arg1;
  845.  
  846.       oldAddr             = varPtr->myAddr;
  847.       oldAbConPtr         = varPtr->myAbConPtr;
  848.       TranslateVar(varPtr, fMap);
  849.  
  850.       KMDTrace(kmdDest, 4, "Result reg Var (0x%01x, 0x%01x) -> (0x%01x, 0x%01x), %s\n",
  851.            oldAddr, oldAbConPtr, varPtr->myAddr, varPtr->myAbConPtr, PPVar(varPtr));
  852.       break;
  853.     }
  854.     default:
  855.       ErrMsg("Bad result reg brand %s\n", PPBrand(p->resultBrand));
  856.       abort();
  857.     }
  858.  
  859.     nextRegs = regs;
  860.  
  861.     if (!SSValidAddr(p, sp)) {
  862.       KMDTrace(kmdDest, 5, "** Empty Stack **");
  863.       break;
  864.     }
  865.     l       = p->regs.l;
  866.     theLink = mDynLinkPtrFromL(l);
  867.     b       = p->regs.b;
  868.     g       = p->regs.g;
  869.  
  870.     while (NonNULL(l) && SSValidAddr(p, l)) {
  871.       cPtr = g->myCodePtr;
  872.       if (!PPValidAddr((SSAddr *) cPtr)) {
  873.     KMDTrace(kmdDest, 5, "Bad code ptr for l = 0x%05x\n", l);
  874.     break;
  875.       }
  876.  
  877.       /* Print the current activation record */
  878.       KMDTrace(kmdDest, 4, "<<< Activation record at %s, line %s >>>\n",
  879.            PPCodePtr(cPtr), PPFindLineNo(cPtr, ip));
  880.       KMDTrace(kmdDest, 5,"b = 0x%05x, g = 0x%05x, sp = 0x%05x, l = 0x%05x\n",
  881.            b, g, sp, l);
  882.       KMDTrace(kmdDest, 5, "ip offset: %d (0x%05x)\n",
  883.            byteOffset(cPtr, ip), byteOffset(cPtr, ip));
  884.       if (IsNULL(cPtr->templateMapOffset)) {
  885.     KMDTrace(kmdDest, 5, "No template IPMap\n");
  886.     break;
  887.       }
  888.       templateMap = (IPMapPtr) addOffset(cPtr, cPtr->templateMapOffset);
  889.       tOffset = IPMapLookup(templateMap, byteOffset(cPtr, ip));
  890.  
  891.       if (IsNULL(tOffset)) {
  892.     KMDTrace(kmdDest, 5, "No template for offset\n", byteOffset(cPtr, ip));
  893.     break;
  894.       }
  895.  
  896.       /*
  897.        * Find the number of arguments and results.
  898.        */
  899.  
  900.       tPtr = (TemplatePtr) addOffset(cPtr, tOffset);
  901.       KMDTrace(kmdDest, 4, "%d entr%s in template\n", tPtr->B.numEntries,
  902.            mPLURALY(tPtr->B.numEntries));
  903.       entry = &tPtr->entry[0];
  904.       argumentCount = resultCount = 0;
  905.       for (k = 0; k < tPtr->B.numEntries; k++, entry++){
  906.     if ((entry->TE.SS.Format == ShortStaticF) &&
  907.         (entry->TE.SS.paramInfo != IsNotParam)) {
  908.       /* There are parameters */
  909.       if (entry->TE.SS.paramInfo == IsArgument) {
  910.         argumentCount += entry->TE.SS.count;
  911.       } else resultCount += entry->TE.SS.count;
  912.     } else break;
  913.       }
  914.       aVar=(AVariablePtr) addOffset((theLink+1),
  915.                     (argumentCount + resultCount) * sizeof(AVariable));
  916.  
  917.       /*
  918.        * Translate parameters (bottom AR only)
  919.        */
  920.  
  921.       entry = &tPtr->entry[0];
  922.       if (IsNULL(theLink->l)) /* do params only for bottom AR*/
  923.     for (k = 0; k < tPtr->B.numEntries; k++, entry++)
  924.       if ((entry->TE.SS.Format == ShortStaticF) &&
  925.           (entry->TE.SS.paramInfo != IsNotParam)) {
  926.  
  927.         /* There are parameters AND it is the bottom AR */
  928.         KMDTrace(kmdDest, 5, "\tShortStaticF\t(%s) %s\tcount =%4d\n", 
  929.              BrandNames[(int)entry->TE.SS.theBrand],
  930.              entry->TE.SS.paramInfo != IsNotParam ? "isParam" : " ",
  931.              entry->TE.SS.count);
  932.         KMDTrace(kmdDest, 4, "%d parameter%s\n", entry->TE.SS.count,
  933.              mPLURAL(entry->TE.SS.count));
  934.         for (i =  entry->TE.SS.count; i > 0 ; i--) {
  935.           aVar--; /* Since we are going backwards */
  936.           TranslateVar(aVar, fMap);
  937.  
  938.           KMDTrace(kmdDest, 5, "%6d: %s #%d: %s\n", byteOffset(l, aVar),
  939.                ((entry->TE.SS.paramInfo == IsArgument) ? "Param" : "Result"),
  940.                i, PPVar(aVar));
  941.         }
  942.       } else break;
  943.  
  944.       /* Translate dynamic link */
  945.       if (IsNULL(theLink->l)) {
  946.     KMDTrace(kmdDest, 4, "%4d: DynamicLink, old  l: 0x%05x  (bottom)\n",
  947.          byteOffset(l, &theLink->l), theLink->l);
  948.     theLink->b      = b;
  949.     theLink->g      = g;
  950.       } else {
  951.     theLink->l  = (SSAddr) addOffset(theLink->l, delta);
  952.     KMDTrace(kmdDest, 4, "%4d: DynamicLink, old  l: 0x%05x  (%d)\n",
  953.          byteOffset(l, &theLink->l), theLink->l, byteOffset(l, theLink->l));
  954.     theLink->b      = (GODP) Map_Lookup(fMap, (int) theLink->b);
  955.     theLink->g      = (GODataPtr) Map_Lookup(fMap, (int) theLink->g);
  956.       }
  957.  
  958.       theLink->ip     = TranslateCodeAddr(fMap, theLink->ip);
  959.  
  960.       KMDTrace(kmdDest, 5, "%4d: DynamicLink, old  g: 0x%05x\n",
  961.            byteOffset(l, &theLink->g), theLink->g);
  962.       KMDTrace(kmdDest, 5, "%4d: DynamicLink, old  b: 0x%05x\n",
  963.            byteOffset(l, &theLink->b), theLink->b);
  964.       KMDTrace(kmdDest, 5, "%4d: DynamicLink, old ip: 0x%05x\n",
  965.            byteOffset(l, &theLink->ip), theLink->ip);
  966.       sAddr = (SSAddr) theLink;
  967.       entry = &tPtr->entry[0];
  968.  
  969.       for (it = 0; it < tPtr->B.numEntries; it++) {
  970.     if (entry->TE.SS.Format == RegisterF) {
  971.       register int             reg, h;
  972.       register TemplateEntryPtr t = entry;
  973.  
  974.       KMDTrace(kmdDest, 5, "\tRegisterF\t(%s),\t%s, r%d, count %d\n",
  975.            BrandNames[(int)t->TE.R.theBrand], 
  976.            t->TE.R.storedWhere == InRegister ? "InRegister" : "InSaveArea",
  977.            t->TE.R.reg, t->TE.R.count);
  978.       if (t->TE.R.storedWhere == InSaveArea) {
  979.         for (reg = t->TE.R.count ; --reg >= 0;) {
  980.           /* Registers are stored low number, low addr */
  981.           sAddr--; /* Since we are going backwards */
  982.           KMDTrace(kmdDest,5,"%4d: Saved Register r%d (0x%06x):\t0x%08x\n",
  983.                byteOffset(l, sAddr), t->TE.R.reg+reg, sAddr, *sAddr);
  984.           /* Remember where register is stored */
  985.           regStoredAt[t->TE.R.reg+reg] = (SSAddr *) sAddr;
  986.           mSetSavedReg(&nextRegs, t->TE.R.reg+reg, *sAddr);
  987.         }
  988.       } else {
  989.         reg = t->TE.R.reg;
  990.         for (h = 0; h < t->TE.R.count; h++, reg++) {
  991.           switch (t->TE.R.theBrand) {
  992.           case DataBrand: {
  993.         KMDTrace(kmdDest, 5, "\tIn r%d: Data:\t0x%08x\n", reg,
  994.              mGetSavedReg(®s, reg));
  995.         break;
  996.           }
  997.           case ODPBrand: {
  998.         ODP         regValue;
  999.         regValue = (ODP) mGetSavedReg(®s, reg);
  1000.         if (NonNIL(regValue)) {
  1001.           regValue = (ODP) Map_Lookup(fMap, (int) regValue);
  1002.         }
  1003.         KMDTrace(kmdDest, 5, "\tIn r%d: ODP:\t0x%08x\t%s\n",
  1004.              reg, regValue, PPODP(regValue));
  1005.         /* Translate the stored value too */
  1006.         if (NonNULL(regStoredAt[reg])) {
  1007.           KMDTrace(kmdDest, 5, "Stored reg #%d at 0x%06x now 0x%06x\n",
  1008.                reg, regStoredAt[reg], regValue);
  1009.           *regStoredAt[reg] = (SSAddr) regValue;
  1010.           regStoredAt[reg] = (SSAddr *) NULL;
  1011.         }
  1012.         break;
  1013.           }
  1014.           case VariableBrand: {
  1015.         AVariable       v;
  1016.         v.myAddr = (DataAddr)     mGetSavedReg(®s, reg);
  1017.         v.myAbConPtr = (AbConPtr) mGetSavedReg(®s, reg+1);
  1018.         KMDTrace(kmdDest, 5, "\tIn r%d-%d:\n", reg, reg+1);
  1019.         TranslateVar(&v, fMap);
  1020.         if (NonNULL(regStoredAt[reg])) {
  1021.           KMDTrace(kmdDest, 5, "Saved reg#%d at 0x%06x now 0x%06x\n",
  1022.                reg, regStoredAt[reg], v.myAddr);
  1023.           *regStoredAt[reg] = (SSAddr) v.myAddr;
  1024.           regStoredAt[reg] =  (SSAddr *) NULL;
  1025.           KMDTrace(kmdDest, 5, "Saved reg#%d at 0x%06x now 0x%06x\n",
  1026.                reg+1, regStoredAt[reg+1], v.myAbConPtr);
  1027.           *regStoredAt[reg+1] = (SSAddr) v.myAbConPtr;
  1028.           regStoredAt[reg+1] = (SSAddr *) NULL;
  1029.         }
  1030.         h++; reg++; /* Since vars take 2 registers */
  1031.         break;
  1032.           }
  1033.           default:
  1034.         ErrMsg("Brand %s not allowed in TraverseAndTranslate\n",
  1035.                PPBrand(t->TE.R.theBrand));
  1036.         (void) abort();
  1037.           } /* end switch (t->TE.R.theBrand) */
  1038.         }
  1039.       }
  1040.       t = (TemplateEntryPtr) addOffset(t, sizeof(t->TE.R));
  1041.       entry = t;
  1042.       continue;
  1043.     }
  1044.     assert(entry->TE.SS.Format == ShortStaticF);
  1045.     if (entry->TE.SS.paramInfo != IsNotParam) {
  1046.       entry++;
  1047.       continue;
  1048.     }
  1049.  
  1050.     KMDTrace(kmdDest, 5, "\tShortStaticF\t(%s)\tcount =%4d\n", 
  1051.          PPBrand(entry->TE.SS.theBrand), entry->TE.SS.count);
  1052.  
  1053.     switch (entry->TE.SS.theBrand) {
  1054.  
  1055.     case DataBrand: {
  1056.       register int            j;
  1057.       int                     intCount;
  1058.       if (entry->TE.SS.count == 1) {
  1059.         ErrMsg("Warning: DataBrand count of 1, translating %s\n", PPODP(fODP));
  1060.         entry->TE.SS.count = 4;
  1061.       }
  1062.  
  1063.       assert (entry->TE.SS.count % sizeof(int) == 0);
  1064.       intCount = entry->TE.SS.count/sizeof(int);
  1065.       for (j = intCount; j > 0; j--) {
  1066.         sAddr--;
  1067.         KMDTrace(kmdDest, 5, "%4d: Data:  0x%08x\n", byteOffset(l, sAddr), *sAddr);
  1068.       }    
  1069.       break;
  1070.     }
  1071.  
  1072.     case ODPBrand: {
  1073.       register int            j;
  1074.       register ODP           *theODPPtr;
  1075.       theODPPtr = (ODP *) sAddr;
  1076.       for (j = 1; j <= entry->TE.SS.count; j++) {
  1077.         theODPPtr--;
  1078.         *theODPPtr = (ODP) Map_Lookup(fMap, (int) *theODPPtr);
  1079.         KMDTrace(kmdDest, 5, "%4d: ODP (0x%05x)\n", 
  1080.              byteOffset(l, theODPPtr), * ((int *) theODPPtr));
  1081.       }
  1082.       sAddr = (SSAddr) theODPPtr;
  1083.       break;
  1084.     }
  1085.  
  1086.     case AddrBrand:
  1087.       sAddr -= entry->TE.SS.count;
  1088.       KMDTrace(kmdDest, 5, "%4d: Address (0x%05x) count %d\n",
  1089.            *(int *)sAddr, entry->TE.SS.count);
  1090.       break;
  1091.  
  1092.  
  1093.     case VectorBrand:
  1094.       if (entry->TE.SS.theBrand == VectorBrand)
  1095.         KMDTrace(kmdDest, 5, "Vector in AR?? ElementBrand = %s\n",
  1096.              BrandNames[(int)entry->TE.SS.elementBrand]);
  1097.       break;
  1098.  
  1099.  
  1100.     case VariableBrand: {
  1101.       register int          j;
  1102.       register AVariablePtr varPtr;
  1103.  
  1104.       for (j = 1; j <= entry->TE.SS.count; j++){
  1105.         sAddr = (SSAddr) addOffset(sAddr, -sizeof(AVariable));
  1106.         varPtr = (AVariablePtr) sAddr;                    
  1107.         /* Translate */
  1108.         oldAbCon = (int) varPtr->myAbConPtr;
  1109.         oldODP   = (int) varPtr->myAddr;
  1110.         TranslateVar(varPtr, fMap);
  1111.         KMDTrace(kmdDest, 5,
  1112.              "%6d: Var (0x%01x, 0x%01x) -> (0x%01x, 0x%01x), %s\n",
  1113.              byteOffset(l, sAddr), oldAbCon, oldODP,
  1114.              varPtr->myAddr, varPtr->myAbConPtr, PPVar(varPtr));
  1115.       }
  1116.       break;
  1117.     }
  1118.  
  1119.     case MonitorBrand:
  1120.       ErrMsg("    *** Monitor in Activation record !!??\n");
  1121.       (void) abort();
  1122.       break;
  1123.  
  1124.     case InvokeQueueBrand: {
  1125.       register InvokeQueuePtr     iq;
  1126.  
  1127.       sAddr = (SSAddr) addOffset(sAddr, -sizeof(InvokeQueue));
  1128.       iq = (InvokeQueuePtr) sAddr;
  1129.       iq->mySSPtr = p;
  1130.       iq->next    = (InvokeQueuePtr) NULL;
  1131.       iq->prev    = (InvokeQueuePtr) NULL;
  1132.       KMDTrace(kmdDest, 5, "%4d: InvokeQueue (0x%05x, 0x%05x)(0x%05x)\n",
  1133.            byteOffset(l, sAddr), *sAddr,  *(sAddr+1), *(sAddr+2));
  1134.       break;
  1135.     }
  1136.  
  1137.     default:
  1138.       ErrMsg("Bad brand %s in mobility.c\n", PPBrand(entry->TE.SS.theBrand));
  1139.       (void) abort();
  1140.     } /* switch */
  1141.  
  1142.     entry = (TemplateEntryPtr)
  1143.       addOffset(entry, sizeof(ShortStatic));
  1144.       }
  1145.  
  1146.       /* The rest is assumed to be variables */
  1147.       {
  1148.     register AVariablePtr   varPtr;
  1149.     varPtr = (AVariablePtr) sAddr;
  1150.     varPtr --;
  1151.     while (SSValidAddr(p, (SSAddr) varPtr) && ( (SSAddr) varPtr >= sp)) {
  1152.       /* Translate */
  1153.       oldAbCon = (int) varPtr->myAbConPtr;
  1154.       oldODP   = (int) varPtr->myAddr;
  1155.       TranslateVar(varPtr, fMap);
  1156.       KMDTrace(kmdDest, 5, "%6d: Var (0x%01x, 0x%01x) -> (0x%01x, 0x%01x), %s\n",
  1157.            byteOffset(l, sAddr), oldAbCon, oldODP,
  1158.            varPtr->myAddr, varPtr->myAbConPtr, PPVar(varPtr));
  1159.       varPtr--;
  1160.     }
  1161.       }
  1162.       /* Now move on to the next AR (link already translated)*/
  1163.       regs    = nextRegs;     /* Note, not all regs relevant */
  1164.       ip      = theLink->ip;
  1165.       regs.b  = b = theLink->b;
  1166.       regs.g  = g = theLink->g;
  1167.       regs.l  = l = theLink->l;
  1168.       sp      = (SSAddr) (theLink+1);
  1169.       theLink = mDynLinkPtrFromL(l);
  1170.     }
  1171.  
  1172.     /* We have reached the bottom of the stack segment */
  1173.  
  1174.     /* Fix the invoke queues */
  1175.     FixInvokeQueue(p);
  1176.  
  1177.     /* Set flags */
  1178.     p->tag.setUpDone        = TRUE;
  1179.     p->ownSSODP->tag.setUpDone = TRUE;
  1180.  
  1181.     /* Enter the process into relevant queue, if necessary */
  1182.     KMDTrace(kmdDest, 3, "%s moved here, status %s in %s\n",
  1183.          PPPOID(p->processOID),PPSSRunStatus((int)p->status.rs),
  1184.          PPSSPlace(p));
  1185.     KMDTrace("LineNumber", 4, "%s moved process arrived in state %s in %s\n",
  1186.          PPPOID(p->processOID), PPSSRunStatus((int)p->status.rs),
  1187.          PPSSPlace(p));
  1188.  
  1189.     switch (p->status.rs) {
  1190.     case SSRunnable:
  1191.       schedule(p);
  1192.       break;
  1193.  
  1194.     case SSInvokeWait:
  1195.       KMDTrace(kmdDest, 3, "%s moved here, waiting on invoke, %s\n",
  1196.            PPPOID(p->processOID), PPSSPlace(p));
  1197.       break;
  1198.  
  1199.     case SSMonWait:
  1200.     case SSCondWait:
  1201.       KMDTrace(kmdDest, 3, "%s\n", PPSSRunStatus((int)p->status.rs));
  1202.       break;
  1203.  
  1204.     default:
  1205.       ErrMsg("Cannot handle process state %d -- sorry\n",
  1206.     PPSSRunStatus((int)p->status.rs));
  1207.     }
  1208.  
  1209.     /* That is all, folks */
  1210.     KMDTrace(kmdDest, 4, "******** Translation of AR done ********\n");
  1211.     break;
  1212.   }
  1213.     
  1214.   default:
  1215.   BADTAG:
  1216.     ErrMsg("Bad tag %s\n", PPODBasicTag(fODP->G.tag.tag));
  1217.     (void) abort();
  1218.   }
  1219.   KMDTrace("FixMe", 2, "Should set tag properly in traverse and translate\n");
  1220.  
  1221.   fODP->G.tag.setUpDone   = TRUE;
  1222.   fODP->G.tag.frozen      = FALSE;
  1223. }
  1224.  
  1225.  
  1226. /*
  1227.  * DoTranslate
  1228.  * Traverse the set and translate each using the translation map
  1229.  * FixMe note:  the fSet should have been a Set, not a Map.
  1230.  * Early versions of the kernel had Maps but no Sets
  1231.  */
  1232. void DoTranslate(fSet, fTMap, isRecovery)
  1233. Set                 fSet;
  1234. Map                 fTMap;
  1235. int isRecovery;
  1236. {
  1237.   Set deferredSet;
  1238.   ODP theODP;
  1239.  
  1240.   if (Set_Count(fSet) == 0) return;
  1241.     
  1242.   deferredSet           = (Set) NULL;
  1243.  
  1244.   Set_For(fSet, theODP)
  1245.     if ((theODP->G.tag.tag == SSTag) || (theODP->G.tag.tag == CondTag)){
  1246.       /* Do SSs and Conditions last */
  1247.       if (IsNULL(deferredSet)) deferredSet = Set_Create();
  1248.       Set_Insert(deferredSet, (int) theODP);
  1249.       continue;
  1250.     }
  1251.     KMDTrace("TT", 5, "Will translate 0x%08.8x one of %s\n", theODP,
  1252.          PPODBasicTag(theODP->G.tag.tag));
  1253.     TraverseAndTranslate(theODP, fTMap, isRecovery);
  1254.   Set_Next;
  1255.  
  1256.   if (IsNULL(deferredSet)) {
  1257.     return;
  1258.   }
  1259.     
  1260.   Set_For(deferredSet, theODP)
  1261.     KMDTrace("TT", 5, "Will translate 0x%08.8x one of %s\n", theODP,
  1262.          PPODBasicTag(theODP->G.tag.tag));
  1263.     TraverseAndTranslate(theODP, fTMap, isRecovery);
  1264.   Set_Next;
  1265.   Set_Destroy(deferredSet);
  1266. }
  1267.  
  1268. HResult MoveCallBack(fReq, fOID)
  1269. GenericReqPtr           fReq;
  1270. OID                     fOID;
  1271. {
  1272.   _realMoveCallBack(fReq, fOID, 0);
  1273. }
  1274. /**********************************************************************/
  1275. /*      MoveCallBack                                                  */
  1276. /**********************************************************************/
  1277. /* Call Back */
  1278. void _realMoveCallBack(fReq, fOID, isRecovery)
  1279. GenericReqPtr           fReq;
  1280. OID                     fOID;
  1281. int isRecovery;
  1282. {
  1283.   register IncomingMoveReqPtr req = (IncomingMoveReqPtr) fReq;
  1284.   char kmdDest[8];
  1285.  
  1286.   strcpy(kmdDest,(isRecovery ? "Recover" : "Move"));
  1287.   KMDTrace(kmdDest, 4, "MoveCallBack; OID %s status %s\n", PPOID(fOID),
  1288.        req->status == IMLoadingCode ? "Loading Code" :
  1289.        req->status == IMCodeLoadDone? "Code load done" :
  1290.        "BAD STATUS");
  1291.  
  1292.   switch (req->status) {
  1293.     
  1294.   case IMLoadingCode: {
  1295.     ODP             oldODP;
  1296.     CodeODP         newODP;
  1297.  
  1298.     /* Requested code has arrived */
  1299.     oldODP          = (ODP) Map_Lookup(req->neededMap, (int) fOID);
  1300.  
  1301.     if (IsNIL(oldODP)) {
  1302.       ErrMsg("MoveCallBack oldODP is nil -- ignored\n");
  1303.       return;
  1304.     }
  1305.     Map_Delete(req->neededMap, (int) fOID);
  1306.  
  1307.     newODP          = (CodeODP) OTLookup(fOID);
  1308.     assert(NonNULL(newODP));
  1309.  
  1310.     /* (Note, m uses the pointer to the code area.) */
  1311.     KMDTrace("TT", 5, "TT Map_Insert: (0x%06x -> 0x%06x) for code %s\n",
  1312.          oldODP, newODP->dataPtr, PPCodePtr(newODP->dataPtr));
  1313.     Map_Insert(req->m, (int) oldODP, (int) newODP->dataPtr);
  1314.  
  1315.     if (Map_Count(req->neededMap) == 0) {
  1316.       KMDTrace(kmdDest, 4, "All needed code loaded\n");
  1317.       req->status = IMCodeLoadDone;
  1318.       _realMoveCallBack((GenericReqPtr) req, (OID) NULL, isRecovery);
  1319.     }
  1320.     break;
  1321.   }
  1322.  
  1323.   case IMCodeLoadDone: {
  1324.  
  1325.  
  1326.     DoTranslate(req->newSet, req->m, isRecovery);
  1327.     
  1328.     /* All done now, cleanup */
  1329.     Map_Destroy(req->m);
  1330.     Map_Destroy(req->neededMap);
  1331.     Set_Destroy(req->newSet);
  1332.  
  1333.     if(isRecovery){
  1334.       /* Gee, where should the recovery process start up?  Lets try here
  1335.        * this code rehashed from MakeObject in kOps.c
  1336.        */
  1337.       CodePtr  cType;
  1338.       register GODP             x;
  1339.       SSPtr p;
  1340.       extern SSPtr NewProcess();
  1341.       
  1342.       /* figure out how to fill the parameters */
  1343.       x = ((GODP)(req->travellerODP));
  1344.       assert(x != (GODP) NULL);
  1345.       if( ((x->dataPtr) != (struct GOData *)NULL) &&
  1346.      ((cType = (CodePtr)(x->dataPtr->myCodePtr))!= (CodePtr)NULL)) {
  1347.     /* Now make a global call of the object's recovery section, if any */
  1348.     if (cType->recovery.offset) {
  1349.       KMDTrace("Recover",4, "Recovery code for object 0x%04x starts\n", x);
  1350.       x->tag.setUpDone        = FALSE;
  1351.       x->tag.frozen           = TRUE;
  1352.       x->tag.isResident       = TRUE;
  1353.       x->dataPtr->tag.setUpDone = FALSE;
  1354.       x->dataPtr->tag.frozen    = TRUE;
  1355.       x->dataPtr->tag.isResident= TRUE;
  1356.       p = NewProcess();
  1357.       StartProcessAtAddr(p, x, x->dataPtr,
  1358.                 (CodeAddr)addOffset(cType,cType->recovery.offset));
  1359.  
  1360.     } else { /* No recovery */
  1361.       x->tag.setUpDone        = TRUE;
  1362.       x->tag.frozen           = FALSE;
  1363.       x->tag.isResident       = TRUE;
  1364.       x->dataPtr->tag.setUpDone = TRUE;
  1365.       x->dataPtr->tag.frozen    = FALSE;
  1366.       x->dataPtr->tag.isResident= TRUE;
  1367.       UnblockInitially(x);
  1368.     }
  1369.       }
  1370.     }
  1371.     FreeRequest((GenericReqPtr) req);
  1372.     break;
  1373.   }
  1374.   default: {
  1375.     ErrMsg("Bad move status %d in MoveCallBack\n", req->status);
  1376.     (void) abort();
  1377.   }
  1378.   }
  1379. }
  1380.  
  1381.  
  1382. /* TriggerCallBacks
  1383.  * 
  1384.  * A service routine for objects which may need to load code before they
  1385.  * check in.  Clients are currently MoveItemHandler and RecoverItemHandler.
  1386.  */
  1387. void TriggerCallBacks(fHandlePtr,itemPtr,isRecovery)
  1388. LMHandle *fHandlePtr;
  1389. MoveItem *itemPtr;
  1390. int isRecovery;
  1391. {
  1392.   register IncomingMoveReqPtr req;
  1393.   OID                 theCTOID;
  1394.   ODP                 theOldODP = NULL;
  1395.   char kmdDest[12];
  1396.   HandlerPtr callBack;
  1397.   HResult RecoverCallBack();
  1398.   extern int onlyFindingOIDs;
  1399.  
  1400.   strcpy(kmdDest,(isRecovery ? "Recover" : "Move"));
  1401. #ifdef CHECKPOINT
  1402.   callBack = (isRecovery ? (GenericHandlerPtr) RecoverCallBack : (GenericHandlerPtr)MoveCallBack);
  1403. #else
  1404.   callBack = (GenericHandlerPtr)MoveCallBack;
  1405. #endif
  1406.  
  1407.   /* Create move/recover request */
  1408.   req                 = mNewRequest(IncomingMove);
  1409.   req->hdr.callBack   = (GenericHandlerPtr)callBack;
  1410.   req->m              = Map_Create();
  1411.   req->neededMap      = Map_Create();
  1412.   req->newSet         = Set_Create();
  1413.  
  1414.   DigestTable(fHandlePtr, req->m, req->neededMap, req->newSet, isRecovery);
  1415.  
  1416.   if(isRecovery){
  1417.     /* here is a vain attempt to stuff an ODP where we can get it
  1418.      * later to start up recovery processes.
  1419.      * rationale: * travellerODP doesn't seem to be used elsewhere.
  1420.      *            * the OID's are definitely assigned at Checkpoint time.
  1421.      * these assertions have not been adequately thought out.
  1422.      */
  1423.     req->travellerODP = OTLookup(itemPtr->oldODP->G.ownOID);
  1424.   }
  1425.  
  1426.   req->status         = IMLoadingCode;
  1427.   if (Map_Count(req->neededMap) > 0) {    /* Have to load some code */
  1428.     Boolean didit;
  1429.     Map     gotLoaded; /* Holds the ones loaded now */
  1430.     CodeODP newODP;
  1431.  
  1432.     KMDTrace(kmdDest, 4, "%s needs to load %d code files\n",
  1433.          kmdDest, Map_Count(req->neededMap));
  1434.  
  1435.     gotLoaded = Map_Create();
  1436.  
  1437.     Map_For(req->neededMap, theCTOID, theOldODP)
  1438.       KMDTrace(kmdDest, 5, "%s must load %s\n", kmdDest, PPCOID(theCTOID));
  1439.       if (isRecovery && onlyFindingOIDs) {
  1440.     fprintf(stdout, "0x%8x\n", theCTOID);
  1441.       } else {
  1442.     didit = LoadRequest(theCTOID, (GenericReqPtr) req);
  1443.     if (didit) Map_Insert(gotLoaded, (int) theCTOID, (int) theOldODP);
  1444.       }
  1445.     Map_Next
  1446.  
  1447.     Map_For(gotLoaded, theCTOID, theOldODP)
  1448.       /* Delete it since no call back will occur */
  1449.       Map_Delete(req->neededMap, (int) theCTOID);
  1450.       newODP      = (CodeODP) OTLookup(theCTOID);
  1451.       assert(NonNULL(newODP));
  1452.       Map_Insert(req->m, (int) theOldODP, (int) newODP->dataPtr);
  1453.       KMDTrace(kmdDest, 5, "%s loaded, (0x%04x -> 0x%04x)\n",
  1454.            PPCOID(theCTOID), theOldODP, newODP->dataPtr);
  1455.     Map_Next
  1456.  
  1457.     Map_Destroy(gotLoaded);
  1458.     if (Map_Count(req->neededMap) > 0) return;
  1459.   }
  1460.  
  1461.   req->status         = IMCodeLoadDone;
  1462.   (*callBack)((GenericReqPtr) req, (OID) NULL);
  1463.   /* Do not forget to destroy maps when done */
  1464. }
  1465.  
  1466. /*
  1467.  * MoveItemHandler
  1468.  */
  1469. HResult MoveItemHandler(fHandlePtr, fHdr)
  1470. LMHandlePtr fHandlePtr;
  1471. ItemHdr     fHdr;
  1472. {
  1473.   int       size, length;
  1474.   MoveItem  item;
  1475.  
  1476.   KMDTrace("Move", 3, "MoveItemHandler\n");
  1477.   size = length = fHdr.size - sizeof(fHdr);
  1478.   LMGetData(fHandlePtr, &item.oldODP, &length);
  1479.   assert (size == length);
  1480.   TriggerCallBacks(fHandlePtr, &item,0);
  1481. }
  1482.  
  1483.  
  1484. /**********************************************************************/
  1485. /*      Move                                                          */
  1486. /**********************************************************************/
  1487.  
  1488. /* Kernel call */
  1489. void Move(fTargetNode, fTargetNodeAbCon)
  1490. GODP                    fTargetNode;
  1491. AbConPtr                fTargetNodeAbCon;
  1492. /* Move the object on top of the stack to the target node
  1493.  * The object is moved.  The reference is popped off the stack,
  1494.  * and the return address is moved down on the stack.
  1495.  * The process continues execution when the move has been initiated.
  1496.  */
  1497. {
  1498.     CodeAddr                returnAddr; /* Return addr */
  1499.     GODP                    theODP;     /* ODP for object to move */
  1500.     AbConPtr                theAbCon;   /* abcon for same */
  1501.     MoveItem                item;       /* stuff to send */
  1502.     Map                     m;          /* ODP moved */
  1503.     Set                     ar;         /* ARs to move */
  1504.     NodeNum                 targetLNN;  /* where to move to */
  1505.     LMHandle                myHandle;   /* handle for the msg to send */
  1506.     KKStatus                kstat;      
  1507.     
  1508.     /* Get object reference from stack */
  1509.     POPIT(currentSSP->regs.sp, returnAddr);
  1510.     POPIT(currentSSP->regs.sp, theODP);
  1511.     POPIT(currentSSP->regs.sp, theAbCon);
  1512.     PUSHIT(currentSSP->regs.sp, returnAddr);
  1513.     KMDTrace("Move", 3, "Move of object (0x%08x, 0x%08x)\n",
  1514.     theODP, theAbCon);
  1515.  
  1516.     /* Start by dispensing with the trivial cases: */
  1517.  
  1518.     if (!PPValidAddr((SSAddr *) theODP) || 
  1519.     !PPValidAddr((SSAddr *) fTargetNode) ||
  1520.     !PPValidAddr((SSAddr *) theODP)
  1521.     ) {
  1522.     KMDTrace("Move", 3, "Object or destination is NIL\n");
  1523.     return;
  1524.     }
  1525.  
  1526.     if (fTargetNode->tag.tag != GODTag) {
  1527.     KMDTrace("Move", 2, "Bad argument to move.\n");
  1528.     fail(preemptRunning());
  1529.     return;
  1530.     }
  1531.     
  1532.     KMDTrace("Move", 4, "Object (tag %s) is one of %s\n",
  1533.     PPODBasicTag(theODP->tag.tag), PPCOID(theAbCon->CodeOID));
  1534.     targetLNN = mGetLocNodeNum(fTargetNode->ownLoc);
  1535.  
  1536.     if (IsNULL(targetLNN)) {
  1537.     KMDTrace("Move", 2, "Target location %s unknown\n",
  1538.         PPLoc(fTargetNode->ownLoc));
  1539.         KMDTrace("Failure", 3, "Attempt to move obj to unknown loc %s\n",
  1540.         PPLoc(fTargetNode->ownLoc));
  1541.     unavail(preemptRunning(), fTargetNode, fTargetNodeAbCon);
  1542.     return;
  1543.     }
  1544.     
  1545.     if (fTargetNode->tag.isResident || targetLNN == GetLNN()) {
  1546.     KMDTrace("Move", 3, "Move to own node; done\n");
  1547.     return;
  1548.     }
  1549.     
  1550.     if (theODP->tag.tag == CondTag) {
  1551.     KMDTrace("Move", 3, "Move of condition 0x%06x ignored\n", theODP);
  1552.         return;
  1553.     }
  1554.     
  1555.     if (theODP->tag.tag != GODTag) {
  1556.     ErrMsg("Cannot move object tagged as %s -- possible compiler error\n",
  1557.         PPODBasicTag(theODP->tag.tag));
  1558.     abort();
  1559.     }
  1560.     
  1561.     /* Is the object remote ? */
  1562.     if (!theODP->tag.isResident) {
  1563.     ErrMsg("Implementation restriction; cannot move remote object - ignored\n");
  1564.     return;
  1565.     }
  1566.  
  1567.     KMDTrace("Move", 5, "  one of %s viewed as %s\n",
  1568.     PPCOID(theAbCon->CodeOID), PPCOID(theAbCon->ATOID));
  1569.  
  1570.     /* OK, go for it */
  1571.  
  1572.     /*
  1573.      * Fix up the invokequeues for the currently running so that it will
  1574.      * be moved too.
  1575.      */
  1576.     
  1577.     FixInvokeQueue(currentSSP);
  1578.  
  1579.     kstat = LMStartMsg(&myHandle, KMSG_EmKernel, EMKM_Item, targetLNN);
  1580.  
  1581.     if (!mSUCCESS(kstat)) {
  1582.     KMDTrace("Move", 2, "%s target node #%d unavailable in %s\n",
  1583.         PPPOID(currentSSP->processOID), PPLoc(fTargetNode->ownLoc),
  1584.             PPSSPlace(currentSSP));
  1585.     KMDTrace("Failure", 3, "%s target node #%d unavailable in %s\n",
  1586.         PPPOID(currentSSP->processOID), PPLoc(fTargetNode->ownLoc),
  1587.             PPSSPlace(currentSSP));
  1588.     unavail(preemptRunning(), theODP, theAbCon);
  1589.     return;
  1590.     }
  1591.  
  1592.     /* Create moved map and set of ARs to send */
  1593.     m                   = Map_Create();
  1594.     ar                  = Set_Create();
  1595.  
  1596.     item.hdr.itemTag    = MoveITag;
  1597.     item.hdr.size       = sizeof(item);
  1598.     item.oldODP         = (ODP) theODP;
  1599.     LMPutData(&myHandle, &item, sizeof(item));
  1600.  
  1601.     MoveToTTable(&myHandle, (ODP) theODP, m, ar);
  1602.  
  1603.     MoveARs(&myHandle, m, ar);
  1604.  
  1605.     /* Clean up */
  1606.     Map_Destroy(m);
  1607.     Set_Destroy(ar);
  1608.     
  1609.     /*
  1610.      * Count number of moves.
  1611.      */
  1612.     cMV_MovesDone++;
  1613.     cMV_MovesBytesSent += LMCurrentPosition(&myHandle);
  1614.     cMV_MovesPacketsSent += LMPacketPosition(&myHandle);
  1615.     
  1616.     kstat = LMSendMsg(&myHandle);
  1617.  
  1618.     if (!mSUCCESS(kstat)) {
  1619.     KMDTrace("Move", 2, "%s target node #%d unavailable in %s\n",
  1620.         PPPOID(currentSSP->processOID), targetLNN, PPSSPlace(currentSSP));
  1621.     unavail(preemptRunning(), theODP, theAbCon);
  1622.     return;
  1623.     }
  1624. }
  1625.  
  1626. /**********************************************************************/
  1627. /*      FixInvokeQueue                                                */
  1628. /**********************************************************************/
  1629.  
  1630. void FixInvokeQueue(fSSPtr)
  1631. /* Ensure that the invoke queues are set up.*/
  1632. register SSPtr               fSSPtr;
  1633. {
  1634.     /* 
  1635.      * Go thru the activation records and insert into invoke queues
  1636.      * until an activation record with the invoke queue is set correctly.
  1637.      */
  1638.     
  1639.     register SSAddr                 l;
  1640.     register DynamicLinkPtr         link;
  1641.     register GODP                   b;
  1642.     register GODataPtr              g;
  1643.     register InvokeQueuePtr         iq;
  1644.     CodeAddr                        ip;
  1645.     
  1646.     l               = fSSPtr->regs.l;
  1647.     if (IsNULL(l)) {
  1648.     KMDTrace("InvokeQueue", 3, "Reached bottom of stack segment\n");
  1649.     return;
  1650.     }
  1651.     b               = fSSPtr->regs.b;
  1652.     g               = fSSPtr->regs.g;
  1653.     ip              = * (CodeAddr *) (fSSPtr->regs.sp);
  1654.     KMDTrace("InvokeQueue", 3, "%s fixing invoke queue at %s",
  1655.     PPPOID(fSSPtr->processOID), PPGetPos((unsigned int) g,
  1656.     (unsigned int) ip));
  1657.  
  1658.     link            = mDynLinkPtrFromL(l);
  1659.     if (mStoppedAtEntry(fSSPtr)) {
  1660.     KMDTrace("InvokeQueue", 3, "Stopped at entry to %s\n",
  1661.         PPSSPlace(fSSPtr));
  1662.     l           = link->l;
  1663.     b           = link->b;
  1664.     g           = link->g;
  1665.     ip          = link->ip;
  1666.     }
  1667.     
  1668.     while (NonNULL(l)) {
  1669.     iq          = mInvokeQueuePtrFromL(l);
  1670.     link        = mDynLinkPtrFromL(l);
  1671.     if (iq->mySSPtr != fSSPtr) break;
  1672.     KMDTrace("InvokeQueue", 3, "Fixing 0x%04x\n", l);
  1673.     KMDTrace("InvokeQueue", 4, "ip = 0x%04x, b = 0x%04x, g = 0x%04x\n",
  1674.         ip, b, g);
  1675.     KMDTrace("InvokeQueue", 4, "at %s\n", PPGetPos((unsigned int) g,
  1676.         (unsigned int) ip));
  1677.  
  1678.     if (IsNULL(b)) {
  1679.         if (IsNULL(link->l)) {
  1680.         /* this is the creation stuff hack, ignore it */
  1681.         } else {
  1682.         ErrMsg("found null b\n");
  1683.         (void) abort();
  1684.         }
  1685.     } else if (b->tag.replicated) {
  1686.         if (IsNULL(link->l)) {
  1687.         /* this is the creation stuff hack, ignore it */
  1688.         } else {
  1689.         ErrMsg("found replicated b, tag: %s\n", PPODTag(b->tag));
  1690.         (void) abort();
  1691.         }
  1692.     } else {
  1693.         iq->mySSPtr     = (SSPtr) - ((int) iq->mySSPtr);
  1694.         InsertDQ((DQueuePtr) &b->ARListHead, (DQueuePtr) iq);
  1695.     }
  1696.  
  1697.     l           = link->l;
  1698.     b           = link->b;
  1699.     g           = link->g;
  1700.     ip          = link->ip;
  1701.     }
  1702.     if (IsNULL(l)) {
  1703.     KMDTrace("InvokeQueue", 3, "Reached bottom of stack segment\n");
  1704.     } else {
  1705.     KMDTrace("InvokeQueue", 3, "Invoke OK in %s",
  1706.         PPGetPos((unsigned int) g, (unsigned int) ip));
  1707.     }
  1708. }
  1709.  
  1710. /**********************************************************************/
  1711. /*      MoveARs                                                       */
  1712. /**********************************************************************/
  1713.  
  1714. void MoveARs(fHandlePtr, fSentMap, fARSet)
  1715. LMHandlePtr         fHandlePtr;
  1716. Map                 fSentMap;
  1717. Set                 fARSet;
  1718. /* Move the ARs in the ARSet */
  1719. {
  1720.     register IncomingIReqPtr    req;
  1721.     register InvokeReqPtr       mReq;
  1722.     GenericPtr                  oldReq;
  1723.     SSAddr          l, topCutAddr, bottomCutAddr, toAddr;
  1724.     SSAddr          thisL, lastL, newL, oldL;
  1725.     CodeAddr        currentIP, topCutIP, bottomCutIP, topPreCutIP,
  1726.             bottomPreCutIP, oldIp;
  1727.     InvokeQueuePtr  iq;
  1728.     DynamicLinkPtr  link, newLink;
  1729.     int             paramSize, sizeOfCut;
  1730.     int             topCutArgCount, topCutResultCount;
  1731.     int             bottomCutArgCount, bottomCutResultCount;
  1732.     int             delta;
  1733.     RegisterSave    regs;
  1734.     RegisterSave    topCutRegs, bottomCutRegs, topPreCutRegs,
  1735.             bottomPreCutRegs;
  1736.     SSPtr           topSSP, middleSSP, bottomSSP, p;
  1737.     SSODP           middleSSODP, bottomSSODP;
  1738.     Boolean         goodAR, sendMiddle;
  1739.     Boolean         sendInitialSS;
  1740.     Set             ssSet;              /* the set of SSs to move */
  1741.     Set             newARSet;           /* any new AR to move */
  1742.  
  1743.     /*
  1744.      * This procedure moves the ARs in the fARSet by
  1745.      * -    Finding all the SS involved.
  1746.      * -    Splitting each involved SS into one or more SSs:
  1747.      *      each of which consists of contiguous ARs that either
  1748.      *      do or do not move.
  1749.      *      Note, that each SS may contain multiple ARs that are to
  1750.      *      be moved.
  1751.      *      After the splitting, each SS consists only of contiguous ARs that
  1752.      *      either should be moved or stay.
  1753.      * -    Move the SSs that need to move.
  1754.      */
  1755.  
  1756.     /*
  1757.      * Search for ARs not in ARList.
  1758.      *  CurrentSSP, ReadyQ, StoppedQ.
  1759.      *  add them to the ssSet.
  1760.      *  This is necessary since processes may wait at the entry to
  1761.      *  operations BEFORE they set up the InvokeQueue.
  1762.      *  (Note, processes waiting on IO and in a Timed Wait need not
  1763.      *  be considered:  These operations are invoked on FIXed objects.)
  1764.      */
  1765.  
  1766.     if (NonNULL(currentSSP) && (
  1767.        (RefStatus) Map_Lookup(fSentMap, (int)currentSSP->regs.b) == RefMoved)
  1768.     ) {
  1769.     KMDTrace("Move", 3, "The currently running SS %s must move\n",
  1770.         PPPOID(currentSSP->processOID));
  1771.     Set_Insert(fARSet, (int) currentSSP->regs.l);
  1772.         /* Preempt it */
  1773.         (void) preemptRunning();
  1774.     }
  1775.     
  1776.     if (NonNULL(readyQ)) {
  1777.         register SSPtr      last, q;
  1778.     last = p = q = readyQ;
  1779.     do {
  1780.             p = p->readyQLink;
  1781.         if ((RefStatus) Map_Lookup(fSentMap, (int) p->regs.b) == RefMoved) {
  1782.         /* Found it, now remove from readyQ and stop it */
  1783.                 /* Delink the one pointed to by p */
  1784.         q->readyQLink = p->readyQLink;
  1785.                 if (p == q) {
  1786.             /* removing the only entry */
  1787.                      readyQ = (SSPtr) NULL;
  1788.         } else if (p == last) {
  1789.                     /* removing the entry at the end of the queue */
  1790.             readyQ = q;
  1791.         }
  1792.         cEmRunnable--;
  1793.  
  1794.         Set_Insert(fARSet, (int) p->regs.l);
  1795.         KMDTrace("Move", 4,
  1796.             "%s: l = 0x%06x to be moved; top AR is %s\n",
  1797.             PPPOID(p->processOID), p->regs.l, PPSSPlace(p));
  1798.         KMDTrace("ProcessSwitch", 3,
  1799.             "%s moving off this node in %s\n", PPPOID(p->processOID),
  1800.             PPSSPlace(p));
  1801.         } else q = p;
  1802.     } while (last != p);
  1803.     }
  1804.  
  1805.     if (NonNULL(stoppedQ)) {
  1806.         register SSPtr      last, q;
  1807.     last = p = q = stoppedQ;
  1808.     do {
  1809.             p = p->readyQLink;
  1810.         if ((RefStatus) Map_Lookup(fSentMap, (int) p->regs.b) == RefMoved) {
  1811.  
  1812.         /* Found it, now remove from readyQ and stop it */
  1813.                 /* Delink the one pointed to by p */
  1814.         q->readyQLink = p->readyQLink;
  1815.                 if (p == q) {
  1816.             /* removing the only entry */
  1817.                     stoppedQ = (SSPtr) NULL;
  1818.         } else if (p == last) {
  1819.                     /* removing the entry at the end of the queue */
  1820.             stoppedQ = q;
  1821.         }
  1822.                 
  1823.         Set_Insert(fARSet, (int) p->regs.l);
  1824.         KMDTrace("Move", 4, "%s: act rec 0x%06x to be moved; at %s\n",
  1825.             PPPOID(p->processOID), p->regs.l, PPSSPlace(p));
  1826.         KMDTrace("ProcessSwitch", 3,
  1827.             "%s moving off this node in %s\n", PPPOID(p->processOID),
  1828.             PPSSPlace(p));
  1829.  
  1830.         } else q = p;
  1831.     } while (last != p);
  1832.     }
  1833.     
  1834.     KMDTrace("FixMe", 3,
  1835.     "Still need to do waiting processes (Locate, Move, Conform)\n");
  1836.  
  1837.     KMDTrace("Move", 4, "There are %d ARs to be moved:\n", Set_Count(fARSet));
  1838.  
  1839.     if (Set_Count(fARSet) == 0) return;
  1840.  
  1841.     /*
  1842.      * Generate list of SSs to be analysed for moving by traversing the set
  1843.      * of ARs to be moved.  At the same time, remove the ARs from their
  1844.      * invokeQueues and mark it as removed by complementing the
  1845.      * SSPtr field (so that it now is back to being a real pointer).
  1846.      */
  1847.  
  1848.     
  1849.     newARSet                = Set_Create();
  1850.     ssSet                   = Set_Create();
  1851.     Set_For(fARSet, l)
  1852.      /* Reset invoke queue */
  1853.         EnsureRemovedFromInvokeQueue(l);
  1854.     iq = mInvokeQueuePtrFromL(l);
  1855.  
  1856.         /* Insert into set of SSs to look at */
  1857.     Set_Insert(ssSet, (int) iq->mySSPtr);
  1858.     KMDTrace("Move", 5, "%s AR l = 0%06x, SS: %s\n",
  1859.         PPPOID(iq->mySSPtr->processOID), l, PPSSPlace(iq->mySSPtr));
  1860.     Set_Next
  1861.     
  1862.  
  1863.    Set_For(ssSet, p)
  1864.     /* Move ARs in the stacksegment p */
  1865.  
  1866.     KMDTrace("Move", 3, "Moving ARs in %s\n", PPPOID(p->processOID));
  1867.  
  1868.         /*
  1869.      * The algorithm for splitting one stack segment containing 
  1870.          * multiple ARs that either move or do not move is kind of hairy.
  1871.          * This code is fairly long;  most of it being concerned with fixing
  1872.      * addresses and setting the right registers.  At the heart of the
  1873.      * algorithm is a loop which crawls down the stack examining one
  1874.      * activation record at a time.  Each time a contiguous set of ARs
  1875.          * that 1. are to move, and 2. are surrounded by non-moving ARs (or
  1876.          * an end of the stack) is found, this set is copied into a new SS
  1877.      * which is then moved.
  1878.          *
  1879.          * Since we cannot have a stack with "holes" in the middle then
  1880.          * every set of contiguous non-moving ARs are also copied, but not
  1881.          * moved.  At the point where the stack is cut the two new pieces are
  1882.      * changed so that it looks like a remote procedure call, i.e., the
  1883.      * top of one SS is set to look like a remote call, while the bottom
  1884.      * of the other SS is set to look like an incoming remote call.
  1885.      */
  1886.  
  1887.         sendInitialSS       = Set_Member(fARSet, (int) p->regs.l);
  1888.         sendMiddle          = ! sendInitialSS;
  1889.  
  1890.         topSSP              = p;
  1891.  
  1892.     /* First time, the IP for the next AR is found on the stack */
  1893.         currentIP           = (CodeAddr) *p->regs.sp;
  1894.         regs                = p->regs;
  1895.  
  1896.     KMDTrace("Move", 4, "Start in AR 0x%06x in %s\n", regs.l,
  1897.         PPSSPlace(p));
  1898.  
  1899.         do {
  1900.         KMDTrace("Move", 4, "In top: AR 0x%04x in %s\n", regs.l,
  1901.         PPRegsPlace(®s, currentIP));
  1902.         if (sendMiddle && !mRegsStoppedAtEntry(®s)) {
  1903.                 /* cannot remove if stopped at entry since no InvkQueue */
  1904.         EnsureRemovedFromInvokeQueue(regs.l);
  1905.         }
  1906.         topPreCutRegs   = regs;
  1907.         topPreCutIP     = currentIP;
  1908.         goodAR = MoveDownStack(®s, ¤tIP);
  1909.     } while (goodAR && (sendMiddle != Set_Member(fARSet, (int) regs.l)));
  1910.  
  1911.         topCutRegs          = regs;
  1912.     topCutIP            = currentIP;
  1913.     
  1914.         if (!goodAR) {
  1915.             if (sendMiddle) {
  1916.         KMDTrace("Move", 3, "Entire SS to stay\n");
  1917.         }
  1918.             KMDTrace("Move", 3, "Entire SS to move\n");
  1919.         MoveSSODToTTable(fHandlePtr, p->ownSSODP, fSentMap, newARSet,
  1920.         p->endOfSS);
  1921.  
  1922.         FreeUpMovedStackSegment(p);
  1923.  
  1924.         continue;
  1925.     }
  1926.  
  1927.         /* There are at least two parts in this SS */
  1928.         
  1929.         if (sendInitialSS) {
  1930.             /* 
  1931.              * Ups, the top must move, handle this specially.
  1932.              * Insert a cut. Send the original SS and make a note
  1933.              * that it should be deleted when done with all the ARs
  1934.              * in it.
  1935.          */
  1936.             KMDTrace("Move", 3, "Top of the stack segment must move\n");
  1937.  
  1938.             /*
  1939.          * Set it up so that the topmost part in the following is called
  1940.          * the middle.
  1941.          */
  1942.         
  1943.         middleSSP       = p;
  1944.         middleSSODP     = middleSSP->ownSSODP;
  1945.             
  1946.             bottomPreCutRegs        = topPreCutRegs;
  1947.         bottomPreCutIP          = topPreCutIP;
  1948.         bottomCutRegs           = topCutRegs;
  1949.             bottomCutIP             = topCutIP;
  1950.         
  1951.         oldReq                  = middleSSP->rPtr;
  1952.  
  1953.         /*
  1954.          * Request for invoke return of middle SS
  1955.          */
  1956.  
  1957.         bottomSSP               = NewStackSegment(p->segmentSize);
  1958.         bottomSSODP             = bottomSSP->ownSSODP;
  1959.  
  1960.         FindParamSizes(&bottomPreCutRegs, bottomPreCutIP,
  1961.         &bottomCutArgCount, &bottomCutResultCount);
  1962.  
  1963.         req                     = mNewRequest(IncomingI);
  1964.         req->status             = IHCodeLoadDone;
  1965.         req->theProcess         = middleSSP;
  1966.         req->i.callerSSOID      = bottomSSP->ownOID;
  1967.         req->i.callerLoc        = bottomSSODP->ownLoc;
  1968.         req->i.argumentCount    = bottomCutArgCount;
  1969.         req->i.resultCount      = bottomCutResultCount;
  1970.         req->i.processOID       = topSSP->processOID;
  1971.         req->i.targetOID        = bottomPreCutRegs.b->ownOID;
  1972.         req->i.targetTryAtLoc   = bottomPreCutRegs.b->ownLoc;
  1973.             req->visitorSet         = (Set) NULL;
  1974.  
  1975.         middleSSP->rPtr         = (GenericPtr) req;
  1976.             
  1977.             /* Set the return at the bottom of the area to move, so that it
  1978.              * will return to the kernel.
  1979.              * Note:  we thus squish the values and need to restore them
  1980.              * after the send since they are needed in the first iteration of
  1981.              * the loop.
  1982.              */
  1983.             link                    = mDynLinkPtrFromL(bottomPreCutRegs.l);
  1984.             oldL                    = link->l;
  1985.             oldIp                   = link->ip;
  1986.         link->l                 = (SSAddr) NULL;
  1987.         link->ip                = (CodeAddr) &ReturnOffStack;
  1988.  
  1989.         paramSize           = sizeof(AVariable) *
  1990.                     (bottomCutArgCount+bottomCutResultCount);
  1991.         bottomCutAddr       = (SSAddr)
  1992.         addOffset(bottomCutRegs.sp, paramSize);
  1993.         sizeOfCut           = (int)
  1994.         byteOffset(middleSSP->regs.sp, bottomCutAddr);
  1995.  
  1996.             KMDTrace("Move", 5, "OK, cut the initialSS at 0x%06x\n",
  1997.         bottomCutAddr);
  1998.         KMDTrace("Move", 5, "Cut %d bytes, paramSize %d\n", sizeOfCut,
  1999.         paramSize);
  2000.         KMDTrace("Move", 5, "bottomPreCut link @ 0x%06x, cut.sp 0x%06x\n",
  2001.         link, bottomCutRegs.sp);
  2002.         
  2003.         /* Send the middleSSP */
  2004.         MoveSSODToTTable(fHandlePtr, middleSSP->ownSSODP, fSentMap,
  2005.         newARSet, bottomCutAddr);
  2006.         
  2007.             /* restore squished dynamic link */
  2008.             link->l                 = oldL;
  2009.         link->ip                = oldIp;
  2010.         
  2011.         /* Note, that this stack segment is freed later */
  2012.             
  2013.             /* We just sent the middle so do not send the next one */
  2014.             sendMiddle              = ! sendMiddle;
  2015.         
  2016.             goto AFTERSEND;
  2017.     }
  2018.     
  2019.     /*
  2020.      * Request for invoke return of top SS
  2021.      */
  2022.     
  2023.     middleSSP       = NewStackSegment(p->segmentSize);
  2024.     middleSSODP     = middleSSP->ownSSODP;
  2025.  
  2026.     FindParamSizes(&topPreCutRegs, topPreCutIP, &topCutArgCount,
  2027.         &topCutResultCount);
  2028.  
  2029.     req                     = mNewRequest(IncomingI);
  2030.     req->status             = IHCodeLoadDone;
  2031.     req->theProcess         = topSSP;
  2032.     req->i.callerSSOID      = middleSSP->ownOID;
  2033.     req->i.callerLoc        = middleSSODP->ownLoc;
  2034.     req->i.argumentCount    = topCutArgCount;
  2035.     req->i.resultCount      = topCutResultCount;
  2036.     req->i.processOID       = topSSP->processOID;
  2037.     req->i.targetOID        = topPreCutRegs.b->ownOID;
  2038.     req->i.targetTryAtLoc   = topPreCutRegs.b->ownLoc;
  2039.         req->visitorSet         = (Set) NULL;
  2040.  
  2041.     oldReq                  = topSSP->rPtr;
  2042.     topSSP->rPtr            = (GenericPtr) req;
  2043.  
  2044.         PREPARENEXTSS:
  2045.  
  2046.         /* In the following, the variable sendMiddle indicates whether or
  2047.          * we are going to send the SS being built. */
  2048.     /* Skip down SS until we find an AR that is to be moved */
  2049.  
  2050.     currentIP           = topCutIP;
  2051.         regs                = topCutRegs;
  2052.  
  2053.         do {
  2054.         KMDTrace("Move", 4, "In middle: AR 0x%04x in %s\n", regs.l,
  2055.         PPRegsPlace(®s, currentIP));
  2056.         if (!mRegsStoppedAtEntry(®s)) {
  2057.         EnsureRemovedFromInvokeQueue(regs.l);
  2058.         }
  2059.         bottomPreCutRegs= regs;
  2060.         bottomPreCutIP  = currentIP;
  2061.         goodAR = MoveDownStack(®s, ¤tIP);
  2062.     } while (goodAR && (sendMiddle == Set_Member(fARSet, (int) regs.l)));
  2063.  
  2064.     /* Save second cut point */
  2065.     bottomCutRegs       = regs;
  2066.     bottomCutIP         = currentIP;
  2067.  
  2068.     /*
  2069.          * Note, in the following, the Boolean flag sendMiddle indicates
  2070.          * whether the middle part (as described below) is to be sent
  2071.          * or if it is to stay (and the top and bottom are to be sent).
  2072.          * On each iteration, the flag is flipped since the old middle
  2073.          * becomes the new top.
  2074.          * To get into this loop you will note a separate handling of the
  2075.          * situations:
  2076.          *      -   the entire stack segment must move (easy).
  2077.          *      -   the entire stack segment must stay (should not occur).
  2078.          *      -   the first AR or (ARs) are to move AND underneath these are
  2079.          *          ARs that are to remain (in this case the loop is
  2080.          *          entered via a goto, search for "goto" above).
  2081.          *
  2082.      * At this point, the first group of ARs to be moved have been
  2083.      * located.  Three stack parts have been identified:
  2084.      *      top                     The non-moving ARs on the top of the SS
  2085.      *      middle                  The first group of ARs to move
  2086.      *      bottom                  The rest.
  2087.      *  
  2088.      * the following variables identify the parts.
  2089.      * 
  2090.      *      Variable:               Describes registers for:
  2091.      *      topPreCutRegs           last non-moving AR, from top.
  2092.      *      topCutRegs              first AR to move, from top.
  2093.      *      bottomPreCutRegs        last AR in first group to move.
  2094.      *      bottomCutRegs           first non-moving AR after group.
  2095.      *
  2096.      * Now we can start cutting.
  2097.      * We cut the stack segment in three.  The top remains but
  2098.      * will have a large hole in the bottom of the segment.
  2099.      * The middle is allocated as a new stack segment.
  2100.          * The bottom will be processes in this loop as the middle part
  2101.          * of the next iteration.
  2102.      */
  2103.  
  2104.     /* Buildup new stack segments and their requests */
  2105.  
  2106.     middleSSP->availStack = p->availStack -
  2107.         byteOffset(bottomCutRegs.sp, p->endOfSS); /* the bottom */
  2108.     middleSSP->processOID = p->processOID;
  2109.  
  2110.     /* Calculate extent of area to copy
  2111.      * the area extends from topCutRegs.sp to the
  2112.      * end of the parameter area for the AR indicated by
  2113.      * bottomPreCutRegs.
  2114.      */
  2115.     topCutAddr          = (SSAddr) topCutRegs.sp;
  2116.     FindParamSizes(&bottomPreCutRegs, bottomPreCutIP,
  2117.         &bottomCutArgCount, &bottomCutResultCount);
  2118.     paramSize           = sizeof(AVariable) *
  2119.                 (bottomCutArgCount+bottomCutResultCount);
  2120.     bottomCutAddr       = (SSAddr)
  2121.         addOffset(bottomCutRegs.sp, paramSize);
  2122.     sizeOfCut           = (int)
  2123.         byteOffset(topCutAddr, bottomCutAddr);
  2124.     toAddr                  = (SSAddr)
  2125.         addOffset(middleSSP->endOfSS, -sizeOfCut);
  2126.  
  2127.     /* Copy into new Stack Segment and retranslate */
  2128.     bcopy((char *) topCutAddr, (char *) toAddr, sizeOfCut);
  2129.     
  2130.     /* set up regs */
  2131.     /* delta is the distance relocated */
  2132.     delta               = (int) byteOffset(topCutAddr, toAddr);
  2133.     middleSSP->regs     = topCutRegs;
  2134.     middleSSP->regs.l   = (SSAddr) addOffset(topCutRegs.l, delta);
  2135.     middleSSP->regs.sp  = (SSAddr) addOffset(topCutRegs.sp, delta);
  2136.     
  2137.     /* Set return address onto stack */
  2138.     PUSHIT(middleSSP->regs.sp,topCutIP);
  2139.  
  2140.     /* traverse and relocate l in the copied ARs */
  2141.     thisL               = topCutRegs.l;
  2142.     link                = mDynLinkPtrFromL(thisL);
  2143.     newLink             = (DynamicLinkPtr) addOffset(link, delta);
  2144.     lastL               = bottomPreCutRegs.l;
  2145.     while (NonNULL(link->l) && (thisL != lastL)) {
  2146.         newL            = (SSAddr) addOffset(link->l, delta);
  2147.         newLink->l      = newL;                
  2148.         newLink         = mDynLinkPtrFromL(newL);
  2149.         thisL           = link->l;
  2150.         link            = mDynLinkPtrFromL(thisL);
  2151.     }
  2152.     /* Set l to NULL at bottom of new SS */
  2153.     newLink->l          = (SSAddr) NULL;
  2154.     newLink->ip         = (CodeAddr) &ReturnOffStack;
  2155.     
  2156.     /* Set l to NULL at bottom of old SS */
  2157.     link                = mDynLinkPtrFromL(topPreCutRegs.l);
  2158.     link->l             = (SSAddr) NULL;
  2159.     link->ip            = (CodeAddr) &ReturnOffStack;
  2160.         
  2161.         /*  end of cutting                                           */
  2162.         /*************************************************************/
  2163.  
  2164.     /* Set up return requests */
  2165.     /* Notes:
  2166.        In the invoke reply message only the following need be set:
  2167.         theProcess
  2168.         i.argumentCount
  2169.         i.resultCount
  2170.         status
  2171.         i.callerSSOID
  2172.         i.callerLoc
  2173.         i.processOID
  2174.         i.targetOID
  2175.         i.targetTryAtLoc (?)
  2176.     */
  2177.  
  2178.  
  2179.         /* Build a request for the middle segment */
  2180.     mReq                    = mNewRequest(Invoke);
  2181.     mReq->status            = IRWaitingForInvokeReply;
  2182.     mReq->requestor         = (SSPtr) middleSSP;
  2183.     mReq->targetGODP        = topPreCutRegs.b;
  2184.     mReq->i                 = req->i;
  2185.     middleSSP->invokePtr    = (GenericPtr) mReq;
  2186.     middleSSP->status.rs    = SSInvokeWait;
  2187.  
  2188.         if (NonNULL(bottomCutRegs.l)) {
  2189.         /*
  2190.          * Request for invoke return of middle SS
  2191.          */
  2192.  
  2193.         bottomSSP               = NewStackSegment(p->segmentSize);
  2194.         bottomSSODP             = bottomSSP->ownSSODP;
  2195.  
  2196.         FindParamSizes(&bottomPreCutRegs, bottomPreCutIP,
  2197.         &bottomCutArgCount, &bottomCutResultCount);
  2198.     
  2199.         req                     = mNewRequest(IncomingI);
  2200.         req->status             = IHCodeLoadDone;
  2201.         req->theProcess         = middleSSP;
  2202.         req->i.callerSSOID      = bottomSSP->ownOID;
  2203.         req->i.callerLoc        = bottomSSODP->ownLoc;
  2204.         req->i.argumentCount    = bottomCutArgCount;
  2205.         req->i.resultCount      = bottomCutResultCount;
  2206.         req->i.processOID       = topSSP->processOID;
  2207.         req->i.targetOID        = bottomPreCutRegs.b->ownOID;
  2208.         req->i.targetTryAtLoc   = bottomPreCutRegs.b->ownLoc;
  2209.             req->visitorSet         = (Set) NULL;
  2210.  
  2211.         middleSSP->rPtr         = (GenericPtr) req;
  2212.     } else {
  2213.             middleSSP->rPtr         = oldReq;
  2214.     }
  2215.  
  2216.         if (sendMiddle) {
  2217.         /* Send the middleSSP */
  2218.             MoveSSODToTTable(fHandlePtr, middleSSP->ownSSODP, fSentMap,
  2219.         newARSet, middleSSP->endOfSS);
  2220.         /* Cleanup */
  2221.             FreeUpMovedStackSegment(middleSSP);
  2222.     }
  2223.  
  2224.         AFTERSEND:
  2225.  
  2226.         /* Check to see if there are more ARs in the stack segment */
  2227.         if (NonNULL(bottomCutRegs.l)) {
  2228.             /* Prepare for next set of ARs */
  2229.         topCutRegs              = bottomCutRegs;
  2230.         topCutIP                = bottomCutIP;
  2231.  
  2232.         topSSP                  = middleSSP;
  2233.             
  2234.             middleSSP               = bottomSSP;
  2235.         middleSSODP             = bottomSSODP;
  2236.         
  2237.             sendMiddle              = !sendMiddle;
  2238.             goto PREPARENEXTSS; /* OK, OK, so I goofed -- should be loop */
  2239.     }
  2240.         
  2241.         if (sendInitialSS) {
  2242.         KMDTrace("Move", 4, "Freeing initial SS %s\n", PPOID(p->ownOID));
  2243.         /* Cleanup */
  2244.         FreeUpMovedStackSegment(p);
  2245.     }
  2246.  
  2247.     Set_Next
  2248.  
  2249.     Set_Destroy(ssSet);
  2250.     
  2251.     /*
  2252.      * Now recursively process the ARs that transitively are to move.
  2253.      */
  2254.     KMDTrace("Move", 4, "Recursively moving %d ARs\n", Set_Count(newARSet));
  2255.     MoveARs(fHandlePtr, fSentMap, newARSet);
  2256.     
  2257.     Set_Destroy(newARSet);
  2258. }
  2259.  
  2260. /**********************************************************************/
  2261. /*      MoveSSODToTTable                                              */
  2262. /**********************************************************************/
  2263.  
  2264. void MoveSSODToTTable(fHandlePtr, fSSODP, fSentMap, fARSet, fHighAddress)
  2265. LMHandle                       *fHandlePtr;
  2266. register SSODP                  fSSODP;
  2267. Map                             fSentMap;
  2268. Set                             fARSet;
  2269. SSAddr                          fHighAddress;
  2270. /*
  2271.  * Add the necessary information to the LMMsg given for sending the SS
  2272.  * given by fODP across the network.  Enter the ODP in the SentMap.
  2273.  * Enter any ARs that are to move in the fARSet.
  2274.  * Do only once for each SSODP -- ignore duplicate requests
  2275.  */
  2276. {
  2277.     CodePtr                 cPtr;
  2278.     register SSPtr          p;
  2279.     register SSAddr         sAddr;
  2280.     register SSAddr         l;
  2281.     RegisterSave            regs;
  2282.     CodeAddr                ip = 0;
  2283.     GODP                    b;
  2284.     GODataPtr               g;
  2285.     SSAddr                  sp;
  2286.     TemplatePtr             tPtr;
  2287.     register TemplateEntryPtr        entry;
  2288.     AVariablePtr            aVar;
  2289.     DynamicLinkPtr          theLink;
  2290.     int                     i, tOffset, it, k, argumentCount, resultCount;
  2291.     int                     sizeOfCut;
  2292.     IPMapPtr                templateMap;
  2293.     TTMoveSSODEntry         ssodentry;
  2294.     RefStatus               status;
  2295.  
  2296.  
  2297.     status = (RefStatus) Map_Lookup(fSentMap, (int) fSSODP);
  2298.     
  2299.     if (((int) status != EMNIL) && (status == RefMoved) ) {
  2300.     KMDTrace("TT", 5, "MoveTT: SS: 0x%05x already moved!!\n", fSSODP);
  2301.     return;
  2302.     }
  2303.  
  2304.     Map_Insert(fSentMap, (int) fSSODP, (int)RefMoved);
  2305.     fSSODP->tag.seenHere    = TRUE;
  2306.  
  2307.     if (IsNULL(fSSODP->ownOID)) {
  2308.     fSSODP->ownOID = fSSODP->dataPtr->ownOID = getNextOID();
  2309.     OTInsert((ODP) fSSODP);
  2310.     }
  2311.     p = (SSPtr) fSSODP->dataPtr;
  2312.     
  2313.     if (IsNULL(p)) {
  2314.     ErrMsg("** NIL stack segment **\n");
  2315.     (void) abort();
  2316.     }
  2317.     
  2318.     KMDTrace("Move", 3, "Moving STACK SEGMENT %s, Process %s in %s\n",
  2319.         PPOID(p->ownOID), PPPOID(p->processOID), PPSSPlace(p));
  2320.     KMDTrace("Move", 5, "SSPtr 0x%05x\n", p);
  2321.     KMDTrace("Move", 3, "Status:\t\t\t%s%s\n", PPSSRunStatus((int)p->status.rs),
  2322.     (mStoppedAtEntry(p) && p->status.rs != SSNotInUse) ?
  2323.     " Stopped at Operation Entry" : "");
  2324.     KMDTrace("Move", 5, "Segment Size: \t\t%4d\n", p->segmentSize);
  2325.     KMDTrace("Move", 5, "Available: \t\t%4d\n", p->availStack);
  2326.     KMDTrace("Move", 5, "splimit:  \t\t0x%06x   (low address)\n", p->splimit);
  2327.     KMDTrace("Move", 5, "sp        \t\t0x%06x   (stack top)\n", p->regs.sp);
  2328.     KMDTrace("Move", 5, "bottom:   \t\t0x%06x   (highest address)\n",
  2329.     fHighAddress);
  2330.     KMDTrace("Move", 5, "SS end:   \t\t0x%06x\n", p->endOfSS);
  2331.     
  2332.     sAddr = sp = p->regs.sp;
  2333.     if (!SSValidAddr(p, sp)) {
  2334.     ErrMsg("** Empty Stack **\n");
  2335.         (void) abort();
  2336.     }
  2337.  
  2338.     ip                      = * (CodeAddr *) sp;
  2339.     l                       = p->regs.l;
  2340.     theLink                 = mDynLinkPtrFromL(l);
  2341.     b                       = p->regs.b;
  2342.     g                       = p->regs.g;
  2343.     regs                    = p->regs;
  2344.  
  2345.     while (NonNULL(l) && SSValidAddr(p, l)) {
  2346.     cPtr = g->myCodePtr;
  2347.     if (IsNULL(cPtr)) {
  2348.         KMDTrace("Move", 5, "Bad code ptr for l = 0x%05x\n", l);
  2349.         break;
  2350.     }
  2351.     
  2352.     /* Print the current activation record */
  2353.     KMDTrace("Move", 4, "\nActivation record at %s, line %s\n",
  2354.         PPCodePtr(cPtr), PPFindLineNo(cPtr, ip));
  2355.     KMDTrace("Move", 5,
  2356.             "b = 0x%05x, g = 0x%05x, sp = 0x%05x, l = 0x%05x\n", b, g, sp, l);
  2357.     KMDTrace("Move", 5, "ip offset: %d (0x%05x)\n", byteOffset(cPtr, ip),
  2358.         byteOffset(cPtr, ip));
  2359.  
  2360.         AddCodeAddrToTTable(fHandlePtr, cPtr, ip, fSentMap, fARSet);
  2361.  
  2362.     if (IsNULL(cPtr->templateMapOffset)) {
  2363.         KMDTrace("Move", 5, "No template IPMap\n");
  2364.         break;
  2365.     }
  2366.     templateMap = (IPMapPtr) addOffset(cPtr, cPtr->templateMapOffset);
  2367.     tOffset = IPMapLookup(templateMap, byteOffset(cPtr, ip));
  2368.     if (IsNULL(tOffset)) {
  2369.         KMDTrace("Move", 5, "No template for offset\n",
  2370.                 byteOffset(cPtr, ip));
  2371.         break;
  2372.     }
  2373.     tPtr = (TemplatePtr) addOffset(cPtr, tOffset);
  2374.     KMDTrace("Move", 5, "%d entr%s in template\n", tPtr->B.numEntries,
  2375.         mPLURALY(tPtr->B.numEntries));
  2376.  
  2377.     /* Traverse the template and find argument and result counts */
  2378.     entry = &tPtr->entry[0];
  2379.     argumentCount = resultCount = 0;
  2380.     for (k = 0; k < tPtr->B.numEntries; k++, entry++) {
  2381.         if ((entry->TE.SS.Format == ShortStaticF) &&
  2382.         (entry->TE.SS.paramInfo != IsNotParam)) {
  2383.         /* There are parameters */
  2384.         if (entry->TE.SS.paramInfo == IsArgument) {
  2385.             argumentCount += entry->TE.SS.count;
  2386.         } else resultCount += entry->TE.SS.count;
  2387.         } else {
  2388.         break;
  2389.         }
  2390.     }
  2391.  
  2392.     entry = &tPtr->entry[0];
  2393.     aVar = (AVariablePtr) addOffset((theLink+1),
  2394.         (argumentCount + resultCount) * sizeof(AVariable));
  2395.     /* aVar now points to the high addr of the parameters */
  2396.  
  2397.     if (IsNULL(theLink->l))
  2398.     for (k = 0; k < tPtr->B.numEntries; k++, entry++)
  2399.     if ((entry->TE.SS.Format == ShortStaticF) &&
  2400.         (entry->TE.SS.paramInfo != IsNotParam)) {
  2401.         /* There are parameters AND this is the bottom AR */
  2402.         KMDTrace("Move", 5,
  2403.         "\tShortStaticF\t(%s) %s\tcount =%4d\n", 
  2404.         BrandNames[(int)entry->TE.SS.theBrand],
  2405.         entry->TE.SS.paramInfo != IsNotParam ? "isParam" : " ",
  2406.         entry->TE.SS.count);
  2407.         KMDTrace("Move", 5, "%d parameter%s\n", entry->TE.SS.count,
  2408.         mPLURAL(entry->TE.SS.count));
  2409.         for (i =  entry->TE.SS.count; i > 0 ; i--) {
  2410.         aVar--;
  2411.         KMDTrace("Move", 5, "%4d: %s #d (0x%05x, 0x%05x), %s\n",
  2412.             byteOffset(l, aVar),
  2413.                     (entry->TE.SS.paramInfo == IsArgument) ? "Param"
  2414.                     : "Result", aVar->myAbConPtr, aVar->myAddr, PPVar(aVar));
  2415.         AddVarToTTable(fHandlePtr, aVar, fSentMap, fARSet);
  2416.         }
  2417.     } else {
  2418.         break;
  2419.     }
  2420.  
  2421.         /* Print the Dynamic Link */
  2422.     if (IsNULL(theLink->l)) {
  2423.         KMDTrace("Move", 5,
  2424.         "%4d: DynamicLink, old  l: 0x%05x  (bottom)\n",
  2425.         byteOffset(l, &theLink->l), theLink->l);
  2426.     } else {
  2427.         KMDTrace("Move", 5, "%4d: DynamicLink, old  l: 0x%05x  (l+%d)\n",
  2428.         byteOffset(l, &theLink->l), theLink->l,
  2429.         byteOffset(l, theLink->l));
  2430.     }
  2431.     KMDTrace("Move", 5, "%4d: DynamicLink, old  g: 0x%05x\n",
  2432.         byteOffset(l, &theLink->g), theLink->g);
  2433.     KMDTrace("Move", 5, "%4d: DynamicLink, old  b: 0x%05x\n",
  2434.         byteOffset(l, &theLink->b), theLink->b);
  2435.     KMDTrace("Move", 5, "%4d: DynamicLink, old ip: 0x%05x\n",
  2436.         byteOffset(l, &theLink->ip), theLink->ip);
  2437.     sAddr = (SSAddr) theLink;
  2438.     entry = &tPtr->entry[0];
  2439.  
  2440.         /* Now traverse the AR data area */
  2441.     for (it = 0; it < tPtr->B.numEntries; it++) {
  2442.         if (entry->TE.SS.Format == RegisterF) {
  2443.         int             reg;
  2444.         register TemplateEntryPtr t = entry;
  2445.         
  2446.         KMDTrace("Move", 5,
  2447.             "\tRegisterF\t(%s),\t%s, r%d, count %d\n",
  2448.             BrandNames[(int)t->TE.R.theBrand], 
  2449.             t->TE.R.storedWhere == InRegister ? "InRegister"
  2450.             : "InSaveArea",
  2451.             t->TE.R.reg, t->TE.R.count);
  2452.         if (t->TE.R.storedWhere == InSaveArea) {
  2453.             for (reg = t->TE.R.count - 1 ; reg >= 0; reg--) {
  2454.             /* Registers are stored low number, low addr */
  2455.             sAddr--; /* Since we are going backwards */
  2456.             KMDTrace("Move", 5,
  2457.                 "%4d: Saved Register r%d:\t0x%08x\t (@ 0x%06x)\n",
  2458.                 byteOffset(l, sAddr), t->TE.R.reg+reg, *sAddr,
  2459.                 sAddr);
  2460.             }
  2461.         } else {
  2462.             for (reg = 0; reg < t->TE.R.count; reg++) {
  2463.             switch (t->TE.R.theBrand) {
  2464.             case DataBrand: {
  2465.                 KMDTrace("Move", 5, "\tIn r%d: Data:\t0x%08x\n",
  2466.                 t->TE.R.reg+reg,
  2467.                 mGetSavedReg(®s, t->TE.R.reg+reg));
  2468.                 break;
  2469.             }
  2470.             case ODPBrand: {
  2471.                 ODP        regValue;
  2472.                 regValue = (ODP)
  2473.                 mGetSavedReg(®s, t->TE.R.reg+reg);
  2474.                 KMDTrace("Move", 5,
  2475.                 "\tIn r%d: ODP:\t0x%08x\t%s\n",
  2476.                 t->TE.R.reg+reg, regValue, PPODP(regValue));
  2477.                 if (entry->TE.R.attachedFlag) {
  2478.                 MoveToTTable(fHandlePtr, regValue, fSentMap,
  2479.                     fARSet);
  2480.                 } else {
  2481.                 AddToTTable(fHandlePtr, regValue, fSentMap,
  2482.                     fARSet);
  2483.                 }
  2484.                 break;
  2485.             }
  2486.             case VariableBrand: {
  2487.                 AVariable       v;
  2488.                 v.myAddr = (DataAddr)
  2489.                 mGetSavedReg(®s, t->TE.R.reg+reg);
  2490.                 v.myAbConPtr = (AbConPtr)
  2491.                 mGetSavedReg(®s, t->TE.R.reg+reg+1);
  2492.                 KMDTrace("Move", 5, "\tIn r%d-%d: Var: %s\n",
  2493.                 t->TE.R.reg+reg, t->TE.R.reg+reg, PPVar(&v)
  2494.                 );
  2495.  
  2496.                 if (entry->TE.R.attachedFlag) {
  2497.                 MoveVarToTTable(fHandlePtr, &v, fSentMap,
  2498.                     fARSet);
  2499.                 } else {
  2500.                 AddVarToTTable(fHandlePtr, &v, fSentMap,
  2501.                     fARSet);
  2502.                 }
  2503.                 reg++; /* Since vars take 2 registers */
  2504.                 break;
  2505.             }
  2506.             default: {
  2507.                 ErrMsg(
  2508.                                 "Brand %d not allowed in MoveSSODToTTable\n",
  2509.                 t->TE.R.theBrand);
  2510.                 (void) abort();
  2511.             }
  2512.  
  2513.             } /* end switch (t->TE.R.theBrand) */
  2514.             }
  2515.         }
  2516.         t = (TemplateEntryPtr) addOffset(t, sizeof(t->TE.R));
  2517.         entry = t;
  2518.  
  2519.         continue;
  2520.         }
  2521.  
  2522.         assert(entry->TE.SS.Format == ShortStaticF);
  2523.         if (entry->TE.SS.paramInfo != IsNotParam) {
  2524.         entry++;
  2525.         continue;
  2526.         }
  2527.  
  2528.         KMDTrace("Move", 5,
  2529.         "\tShortStaticF\t(%s)\tcount =%4d\n", 
  2530.         BrandNames[(int)entry->TE.SS.theBrand],
  2531.         entry->TE.SS.count);
  2532.  
  2533.         switch (entry->TE.SS.theBrand) {
  2534.         case DataBrand: {
  2535.         register int            j;
  2536.         int                     intCount;
  2537.         assert (entry->TE.SS.count % sizeof(int) == 0);
  2538.         intCount = entry->TE.SS.count/sizeof(int);
  2539.         for (j = intCount; j > 0; j--) {
  2540.             sAddr--;
  2541.             KMDTrace("Move", 5, "%4d: Data:  \t0x%08x\n",
  2542.             byteOffset(l, sAddr), *sAddr);
  2543.         }    
  2544.         break;
  2545.         }
  2546.  
  2547.         case ODPBrand: {
  2548.         register int            j;
  2549.         register ODP           *theODPPtr;
  2550.         theODPPtr = (ODP *) sAddr;
  2551.         for (j = 1; j <= entry->TE.SS.count; j++) {
  2552.             theODPPtr--;
  2553.             KMDTrace("Move", 5, "%4d: ODP \t(0x%05x)\n", 
  2554.             byteOffset(l, theODPPtr), * ((int *) theODPPtr));
  2555.             if (entry->TE.SS.attachedFlag) {
  2556.             MoveToTTable(fHandlePtr, (ODP) *theODPPtr, fSentMap,
  2557.                 fARSet);
  2558.             } else {
  2559.             AddToTTable(fHandlePtr, (ODP) *theODPPtr, fSentMap,
  2560.                 fARSet);
  2561.             }
  2562.         }
  2563.         
  2564.         sAddr = (SSAddr) theODPPtr;
  2565.         break;
  2566.         }
  2567.         
  2568.         case AddrBrand:{
  2569.         sAddr -= entry->TE.SS.count;
  2570.         KMDTrace("Move", 5, "%4d: Address \t(0x%05x) count %d\n",
  2571.             *(int *)sAddr, entry->TE.SS.count);
  2572.         (void) abort();
  2573.         }
  2574.         
  2575.         case VectorBrand: {
  2576.         KMDTrace("Move", 5, "Vector (in SS ??) ElementBrand = %s\n",
  2577.             BrandNames[(int)entry->TE.SS.elementBrand]);
  2578.         assert(entry->TE.SS.theBrand != VectorBrand);
  2579.                 (void) abort();
  2580.         break;
  2581.         }
  2582.         
  2583.         case VariableBrand: {
  2584.         register int            j;
  2585.         register AVariablePtr   varPtr;
  2586.  
  2587.         for (j = 1; j <= entry->TE.SS.count; j++){
  2588.             sAddr = (SSAddr) addOffset(sAddr, -sizeof(AVariable));
  2589.             varPtr = (AVariablePtr) sAddr;                    
  2590.             KMDTrace("Move", 5,
  2591.                         "%4d: Variable\t(0x%04x, 0x%04x) %s\n",
  2592.                         byteOffset(l, sAddr), varPtr->myAddr,
  2593.             varPtr->myAbConPtr, PPVar(varPtr));
  2594.             if (entry->TE.SS.attachedFlag) {
  2595.             MoveVarToTTable(fHandlePtr, varPtr, fSentMap, fARSet);
  2596.             } else {
  2597.             AddVarToTTable(fHandlePtr, varPtr, fSentMap, fARSet);
  2598.             }
  2599.         }
  2600.         break;
  2601.         }
  2602.         
  2603.         case MonitorBrand: {
  2604.         sAddr = (SSAddr) addOffset(sAddr, sizeof(MonitorLock));
  2605.         ErrMsg("    *** Monitor in Activation record !!??\n");
  2606.                 (void) abort();
  2607.         break;
  2608.         }
  2609.         
  2610.         case InvokeQueueBrand: {
  2611.         sAddr = (SSAddr) addOffset(sAddr, -sizeof(InvokeQueue));
  2612.         if (*(sAddr+2) < 0) {
  2613.             KMDTrace("Move", 5,
  2614.             "%4d: InvokeQueue\t(0x%05x, 0x%05x) *(0x%05x)\n",
  2615.             byteOffset(l, sAddr), *sAddr,  *(sAddr+1),
  2616.             - (*(sAddr+2)));
  2617.         } else {
  2618.             KMDTrace("Move", 5,
  2619.             "%4d: InvokeQueue\t(0x%05x, 0x%05x)  (0x%05x)\n",
  2620.             byteOffset(l, sAddr), *sAddr,  *(sAddr+1),
  2621.             (*(sAddr+2)));
  2622.         }
  2623.         break;
  2624.         }
  2625.  
  2626.         default: {
  2627.         KMDTrace("Move", 5, "Bad brand %s in MoveSSODToTTable\n",
  2628.             PPBrand(entry->TE.SS.theBrand));
  2629.                 (void) abort();
  2630.         }
  2631.  
  2632.         } /* end switch (entry->TE.SS.theBrand) */
  2633.  
  2634.         entry = (TemplateEntryPtr)
  2635.         addOffset(entry, sizeof(ShortStatic));
  2636.     }
  2637.     
  2638.     /* The rest is assumed to be variables */
  2639.     {
  2640.         register AVariablePtr   varPtr;
  2641.         varPtr = (AVariablePtr) sAddr;
  2642.         varPtr --;
  2643.         while (SSValidAddr(p, (SSAddr) varPtr) && 
  2644.         ( (SSAddr) varPtr >= sp)) {
  2645.         KMDTrace("Move", 5, "%4d: Variable (0x%04x, 0x%04x), %s\n",
  2646.             byteOffset(l, varPtr),
  2647.             varPtr->myAddr, varPtr->myAbConPtr, PPVar(varPtr));
  2648.         AddVarToTTable(fHandlePtr, varPtr, fSentMap, fARSet);
  2649.         varPtr--;
  2650.         }
  2651.     }
  2652.     KMDTrace("Move", 5,
  2653.         "\n********** End of activation record *********\n");
  2654.     
  2655.     /* Now move on to the next activation record */
  2656.  
  2657.     /* Restore registers from register save area */
  2658.     
  2659.     entry       = &tPtr->entry[0];
  2660.     sAddr       = (SSAddr) theLink;
  2661.     for (i = 0; i < tPtr->B.numEntries; i++) {
  2662.     
  2663.         switch (entry->TE.SS.Format) {
  2664.     
  2665.         case ShortStaticF: {
  2666.         KMDTrace("Move", 5,
  2667.             "\tShortStaticF\t(%s) %s\tcount =%4d\tsAddr 0x%06x\n",
  2668.             BrandNames[(int)entry->TE.SS.theBrand],
  2669.             entry->TE.SS.paramInfo != 0 ? "isParam" : " ",
  2670.             entry->TE.SS.count, sAddr);
  2671.     
  2672.         if (entry->TE.SS.paramInfo != IsNotParam) {
  2673.             entry++;
  2674.             continue;
  2675.         }
  2676.  
  2677.         switch (entry->TE.SS.theBrand) {
  2678.     
  2679.         case DataBrand: {
  2680.             sAddr = (SSAddr)
  2681.             addOffset(sAddr, -entry->TE.SS.count);
  2682.             break;
  2683.         }
  2684.         
  2685.         case ODPBrand: {
  2686.             sAddr = (SSAddr)
  2687.             addOffset(sAddr, -sizeof(ODP)*entry->TE.SS.count);
  2688.             break;
  2689.         }
  2690.         
  2691.         case AddrBrand:{
  2692.             assert(entry->TE.SS.theBrand != AddrBrand);
  2693.                     (void) abort();
  2694.             break;
  2695.         }
  2696.     
  2697.         case VectorBrand: {
  2698.             break;
  2699.         } /* case Vector Brand */
  2700.         
  2701.         case VariableBrand: {
  2702.             sAddr = (SSAddr)
  2703.             addOffset(sAddr, -sizeof(AVariable)*entry->TE.SS.count);
  2704.             break;
  2705.         }
  2706.  
  2707.         case MonitorBrand: {
  2708.             sAddr = (SSAddr)
  2709.             addOffset(sAddr, -sizeof(MonitorLock));
  2710.             ErrMsg("MonitorBrand in AR\n");
  2711.             assert(entry->TE.SS.theBrand != MonitorBrand);
  2712.             (void) abort();
  2713.         }
  2714.         
  2715.         case InvokeQueueBrand: {
  2716.             sAddr = (SSAddr) addOffset(sAddr, -sizeof(InvokeQueue));
  2717.             break;
  2718.         }
  2719.         
  2720.         default: {
  2721.             ErrMsg("Bad brand %s in MoveSSODToTTable (ARend)\n",
  2722.             PPBrand(entry->TE.SS.theBrand));
  2723.             (void) abort();
  2724.             break;
  2725.         }
  2726.     
  2727.         } /* end switch (entry->TE.SS.theBrand) */
  2728.     
  2729.         entry = (TemplateEntryPtr)
  2730.                     addOffset(entry, sizeof(ShortStatic));
  2731.         break;
  2732.         }
  2733.     
  2734.         case RegisterF: {
  2735.         KMDTrace("Move", 5,
  2736.             "\tRegisterF\t(%s),\t%s, r%d, count %d, sAddr 0x%06x\n",
  2737.             BrandNames[(int)entry->TE.R.theBrand], 
  2738.             entry->TE.R.storedWhere == InRegister ? "InRegister"
  2739.             : "InSaveArea", entry->TE.R.reg, entry->TE.R.count,
  2740.             sAddr);
  2741.         if (entry->TE.R.storedWhere == InSaveArea) {
  2742.             for (k = entry->TE.R.count - 1 ; k >= 0; k--) {
  2743.             /* Registers are stored low number, low addr */
  2744.             sAddr--; /* Since we are going backwards, do -- first */
  2745.             KMDTrace("Move", 5,
  2746.                 "Restoring r%d, was 0x%02x, now 0x%02x from 0x%06x\n", 
  2747.                 entry->TE.R.reg+k,
  2748.                 mGetSavedReg(®s, entry->TE.R.reg+k),
  2749.                 *sAddr, sAddr);
  2750.             mSetSavedReg(®s, entry->TE.R.reg+k, *sAddr);
  2751.             }
  2752.         }
  2753.         entry = (TemplateEntryPtr)
  2754.                     addOffset(entry, sizeof(entry->TE.R));
  2755.         break;
  2756.         } /* case RegisterF */
  2757.     
  2758.         default: {
  2759.         ErrMsg("Bad format 0x%02x in MoveSSODToTTable\n",
  2760.             entry->TE.SS.Format);
  2761.         (void) abort();
  2762.         break;
  2763.         } /* default action */
  2764.     
  2765.         } /* switch on entry->TE.SS.Format */
  2766.     } /* for (i = 0; ...) */
  2767.     
  2768.     
  2769.     ip      = theLink->ip;
  2770.     b       = theLink->b;
  2771.     g       = theLink->g;
  2772.     l       = theLink->l;
  2773.     sp      = (SSAddr) (theLink+1);
  2774.     theLink = mDynLinkPtrFromL(l);
  2775.     } /* while there are more ARs */
  2776.  
  2777.     /* Send the CodeAddr for the return (a kernel addr) */
  2778.     AddCodeAddrToTTable(fHandlePtr, (CodePtr) NULL, ip, fSentMap, fARSet);
  2779.  
  2780.     /* Now send the Requests */
  2781.     if (NonNULL(p->rPtr)) {
  2782.     AddReqToTTable(fHandlePtr, p->rPtr, fSentMap, fARSet);
  2783.     }
  2784.     
  2785.     if (NonNULL(p->invokePtr)) {
  2786.     AddReqToTTable(fHandlePtr, p->invokePtr, fSentMap, fARSet);
  2787.     }
  2788.     
  2789.     /* Send the result registers (if not DataBrand) */
  2790.     switch (p->resultBrand){
  2791.     case DataBrand: {
  2792.     KMDTrace("Move", 4, "Result regs data: (0x%04x,0x%04x)\n", p->regs.arg1,
  2793.         p->regs.arg2);
  2794.     break;
  2795.     }
  2796.     case ODPBrand: {
  2797.     KMDTrace("Move", 4, "Result reg ODP: %s\n",
  2798.         PPODP((ODP) p->regs.arg1));
  2799.         AddToTTable(fHandlePtr, (ODP) p->regs.arg1, fSentMap, fARSet);
  2800.     break;
  2801.     }
  2802.     case VariableBrand: {
  2803.     KMDTrace("Move", 4, "Result reg Var: %s\n",
  2804.         PPVar((AVariablePtr) &p->regs.arg1));
  2805.     AddVarToTTable(fHandlePtr, (AVariablePtr) p->regs.arg1, fSentMap,
  2806.         fARSet);
  2807.     break;
  2808.     }
  2809.     default: {
  2810.     ErrMsg("Bad result reg brand %s\n", PPBrand(p->resultBrand));
  2811.     abort();
  2812.     }
  2813.     }
  2814.     
  2815.     /* Send the SS */
  2816.     sizeOfCut               = byteOffset(p->regs.sp, fHighAddress);
  2817.     ssodentry.hdr.itemTag   = TTMoveSSODITag;
  2818.     ssodentry.hdr.size      = sizeof(TTMoveSSODEntry) + sizeOfCut;
  2819.     KMDTrace("Move", 4, "Size of SSOD: %d + %d = %d\n",
  2820.     sizeof(TTMoveSSODEntry), sizeOfCut, ssodentry.hdr.size);
  2821.     UpdateLocation(fSSODP->ownOID, NewLocation(fSSODP->ownLoc,
  2822.     ((*fHandlePtr)->mmMsgHdr.MsgDest)), GetLNN());
  2823.     p->tag.isResident       =
  2824.     fSSODP->tag.isResident  = FALSE;
  2825.     
  2826.     /* Fill in ssodentry */
  2827.     ssodentry.tag           = p->tag;
  2828.     ssodentry.ownOID        = p->ownOID;
  2829.     ssodentry.ownLoc        = fSSODP->ownLoc;
  2830.     ssodentry.processOID    = p->processOID;
  2831.     ssodentry.oldSSPtr      = p;
  2832.     ssodentry.oldReadyQLink = p->readyQLink;
  2833.     ssodentry.status        = p->status;
  2834.     ssodentry.availStack    = p->availStack;
  2835.     ssodentry.thisSegmentSize = p->segmentSize;
  2836.     ssodentry.regs          = p->regs;
  2837.     ssodentry.resultBrand   = p->resultBrand;
  2838.     ssodentry.rPtr          = p->rPtr;
  2839.     ssodentry.invokePtr     = p->invokePtr;
  2840.  
  2841.     LMPutData(fHandlePtr, &ssodentry, sizeof(TTMoveSSODEntry));
  2842.     LMPutData(fHandlePtr, p->regs.sp, sizeOfCut);
  2843.     
  2844. }
  2845.  
  2846. /**********************************************************************/
  2847. /**********************************************************************/
  2848. /*      MoveProcessQueueToTTable                                      */
  2849. /**********************************************************************/
  2850. /*ARGSUSED*/
  2851. void MoveProcessQueueToTTable(fHandlePtr, fHeadSSPtr, fSentMap, fARSet)
  2852. LMHandle                       *fHandlePtr;
  2853. register SSPtr                  fHeadSSPtr;
  2854. Map                             fSentMap;
  2855. Set                             fARSet;
  2856. /* This procedure moves the processes queue pointed to by fHeadSSPtr
  2857.  * into the TTable for transmission over the net.
  2858.  */
  2859.  
  2860. {
  2861.     register SSPtr              p;
  2862.     /*
  2863.      * Traverse the list and put the top AR of each process into the ARSet.
  2864.      * This ensures that the processes will be moved when the ARSet is
  2865.      * processed.
  2866.      */
  2867.     KMDTrace("Move", 4, "Moving Process Queue\n");
  2868.     p = fHeadSSPtr;
  2869.     if (NonNULL(p)) {
  2870.          do {
  2871.         p = p->readyQLink;
  2872.         KMDTrace("Move", 4, "\t%s in %s\n", PPPOID(p->processOID),
  2873.         PPSSPlace(p));
  2874.         KMDTrace("Move", 4, "Adding l = 0x%06x to ARSet\n", p->regs.l);
  2875.         Set_Insert(fARSet, (int) p->regs.l);    
  2876.     } while (p != fHeadSSPtr);
  2877.     }
  2878. }
  2879.  
  2880. /**********************************************************************/
  2881. /*      MoveCondToTTable                                              */
  2882. /**********************************************************************/
  2883. void MoveCondToTTable(fHandlePtr, fCondODP, fSentMap, fARSet)
  2884. LMHandle                       *fHandlePtr;
  2885. register CondODP                fCondODP;
  2886. Map                             fSentMap;
  2887. Set                             fARSet;
  2888. {
  2889.     KMDTrace("Move", 4, "Moving Condition 0x%06x\n", fCondODP);
  2890.     
  2891.     /* First move the process queue */
  2892.     MoveProcessQueueToTTable(fHandlePtr, fCondODP->waiting, fSentMap, fARSet);
  2893.  
  2894.     moveCondEntry.oldODP        = (ODP) fCondODP;
  2895.     if (IsNULL(fCondODP->ownOID)) {
  2896.     OTInsert((ODP) fCondODP);
  2897.     }
  2898.     fCondODP->tag.seenHere      = TRUE;
  2899.     fCondODP->tag.isResident    = FALSE;
  2900.     fCondODP->ownLoc            = NewLocation(fCondODP->ownLoc,
  2901.     (*fHandlePtr)->mmMsgHdr.MsgDest);
  2902.  
  2903.     moveCondEntry.tag           = fCondODP->tag;
  2904.     moveCondEntry.ownOID        = fCondODP->ownOID;
  2905.     moveCondEntry.ownLoc        = fCondODP->ownLoc;
  2906.     moveCondEntry.theLock       = fCondODP->theLock;
  2907.     moveCondEntry.theWaiting    = fCondODP->waiting;
  2908.     
  2909.     KMDTrace("TT", 4,
  2910.     "AddTT: MoveCond(%s) 0x%06x monLock 0x%06x from %s, waiting 0x%06x\n",
  2911.         PPOID(fCondODP->ownOID), fCondODP, fCondODP->theLock,
  2912.     PPLoc(fCondODP->ownLoc), fCondODP->waiting);
  2913.  
  2914.     LMPutData(fHandlePtr, &moveCondEntry, sizeof(moveCondEntry));
  2915.  
  2916.     Map_Insert(fSentMap, (int) fCondODP, (int) RefMoved);
  2917.     
  2918.     DeActivateCond(fCondODP);
  2919.     
  2920. }
  2921.  
  2922. /**********************************************************************/
  2923. /*      MoveMonitorToTTable                                           */
  2924. /**********************************************************************/
  2925. void MoveMonitorToTTable(fHandlePtr, fMonitorLockPtr, fSentMap, fARSet)
  2926. LMHandle                       *fHandlePtr;
  2927. register MonitorLockPtr         fMonitorLockPtr;
  2928. Map                             fSentMap;
  2929. Set                             fARSet;
  2930. /* Move the monitor and its conditions */
  2931. {
  2932.     Set                     theSet;
  2933.     CondODP                 aCondODP;
  2934.  
  2935.     /*
  2936.      * First move the queue of waiting processes.
  2937.      */
  2938.     if (NonNULL(fMonitorLockPtr->waiting)) {
  2939.         MoveProcessQueueToTTable(fHandlePtr, fMonitorLockPtr->waiting,
  2940.         fSentMap, fARSet);
  2941.     }
  2942.     
  2943.     /* Conditions are handled  specially.  If the condition
  2944.        is within an object which is moving then the condition
  2945.        must also be moved.  The set of waiting processes is
  2946.        represented in a queue originating in the CondOD.
  2947.      */
  2948.     
  2949.     theSet  = (Set) Map_Lookup(condMap, (int) fMonitorLockPtr);
  2950.     if (IsNIL(theSet)) {
  2951.     KMDTrace("Move", 5, "No conditions tied to Mon Lock 0x%06x\n",
  2952.         fMonitorLockPtr);
  2953.     return;
  2954.     }
  2955.     
  2956.     /*
  2957.       * Go thru the set of conditions tied to the monitor and move them.  The
  2958.       * monitorlock parts are moved automaticaly since they are contained in
  2959.       * the data area of the object.
  2960.       */
  2961.     Set_For(theSet, aCondODP)
  2962.     MoveCondToTTable(fHandlePtr, aCondODP, fSentMap, fARSet);
  2963.     Set_Next;
  2964.  
  2965.     /* Cleanup */
  2966.     Set_Destroy(theSet);
  2967.     Map_Delete(condMap, (int) fMonitorLockPtr);
  2968. }
  2969.  
  2970. /**********************************************************************/
  2971. /*      MoveInit                                                      */
  2972. /**********************************************************************/
  2973.  
  2974. void MoveInit()
  2975. {
  2976.     KMDSetTrace(Move);
  2977.     KMDTrace("Move", 5, "MoveInit\n");
  2978.     KMDSetTrace(InvokeQueue);
  2979.     KMDTrace("InvokeQueue", 5, "InvokeQueue trace level 5\n");
  2980.  
  2981.     SetItemHandler(MoveITag, MoveItemHandler);
  2982. }
  2983.  
  2984. /* Copyright 1986 Eric Jul */
  2985.